2017-04-18 46 views
1

我目前有一種討厭的代碼塊,我正在寫一個程序,模擬螃蟹的生長(令人興奮的東西.....)。該程序後來被更大的仿真吸收,因此代碼速度很重要。我最慢的代碼塊之一包含這個討厭的分支邏輯。我希望有人能想辦法讓這個更有效....蟒蛇 - 優化分支邏輯

對於背景下,這個代碼塊基本上是說:「我是不是再生爪如果有哪一個如果左/右?爪再生長,是它的顯性或非慣用手鑑於此,應用此號碼XYZ」

if left_or_right_growing == 'left': 
    if crab.rightclawCrusher == True: 
     crab.rightclaw_size = new_crushersize 
     if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth 
      crab.leftclaw_size = max(new_pincersize * crab.proportion_of_new_claw_thats_grownback()+adj, crab.leftclaw_size) 
    elif crab.rightclawCrusher == False: 
     crab.rightclaw_size = new_pincersize + adj 
     if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth 
      crab.leftclaw_size = max(new_crushersize * crab.proportion_of_new_claw_thats_grownback(), crab.leftclaw_size) 

elif left_or_right_growing == 'right': 
    if crab.rightclawCrusher == True: 
     crab.leftclaw_size = new_pincersize + adj 
     if crab.moltnumber_for_claw_removal_right < crab.numberofmolts: #so it doesn't overwrite budding claw growth 
      crab.rightclaw_size = max(new_crushersize * crab.proportion_of_new_claw_thats_grownback(), crab.rightclaw_size) 
    elif crab.rightclawCrusher == False: 
     crab.leftclaw_size = new_crushersize 
     if crab.moltnumber_for_claw_removal_right < crab.numberofmolts: #so it doesn't overwrite budding claw growth 
      crab.rightclaw_size = max(new_pincersize * crab.proportion_of_new_claw_thats_grownback() +adj, crab.rightclaw_size) 

elif left_or_right_growing == 'both': 
    pro_left, pro_right = crab.proportion_of_new_claw_thats_grownback() 
    if pro_left > 1. or pro_right > 1.: 
     print('ERROR IN TRANFORM: pro_left: ' + str(pro_left) +' pro_right: ' + str(pro_right)) 
    if crab.rightclawCrusher == True: 
     if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth 
      crab.leftclaw_size = max(new_pincersize * pro_left+ adj, crab.leftclaw_size) 

     if crab.moltnumber_for_claw_removal_right < crab.numberofmolts: 
      crab.rightclaw_size = max(new_crushersize * pro_right, crab.rightclaw_size)      

    else: 
     if crab.moltnumber_for_claw_removal_right < crab.numberofmolts: #so it doesn't overwrite budding claw growth 
      crab.rightclaw_size = max(new_pincersize * pro_right+ adj, crab.rightclaw_size) 

     if crab.moltnumber_for_claw_removal_left < crab.numberofmolts:  
      crab.leftclaw_size = max(new_crushersize * pro_left, crab.leftclaw_size) 
+1

更改'elif​​== False:'只是'else:'如果唯一的可能性是'True'和'False'。 – Barmar

+0

有什麼方法可以緩存所有測試的結果,所以您不必每次都重複它們? – Barmar

+0

不幸的是,它們是動態的,並且會週期性地發生變化(即,不像人類,我總是會右手) – keynesiancross

回答

2

關閉以前的人說你可以爲所有的嵌套if語句創建一個函數這是在你的三個條件之後出現的。然後你會把它們放在一本字典中,並像這樣對它們進行調用。這裏有一個例子說明這個方法:

def fizz(x, y): 
    return x*y 

def foo(k, v): 
    return k - v 

def buzz(a, b): 
    return a + b 

然後你做一個字典作爲這樣的:

opts = {'left':fizz, 'right':foo, 'both':buzz} 

那麼你的代碼應該是這樣的:

if left_or_right_growing == 'left': 
    opts['left'](1,2) 
    ## output is 2 

elif left_or_right_growing == 'right': 
    opts['right'](3,4) 
    ## output is -1 

elif left_or_right_growing == 'both': 
    opts['both'](5,6) 
    ## output is 11 

並回答問題你向另一個人提出,是的,這個方法最終應該比一堆嵌套的if語句更快。對你的代碼進行基準測試,看看會發生什麼。

編輯:

real 0m0.020s 
user 0m0.010s 
sys  0m0.007s 

,然後當我用你的方法和替換功能,用它自己的,如果循環:

real 0m0.037s 
user 0m0.012s 
sys  0m0.009s 

這裏是腳本中使用我的方法有些樣品基準我用來測試功能方法:

import sys 

def fizz(crab, x, y): 
    if crab == 2: 
     print 'Hello' 
    else: 
     return x*y 

def foo(crab, k, v): 
    if crab == 2: 
     print 'Hello' 
    else: 
     return k - v 

def buzz(crab, a, b): 
    if crab == 2: 
     print 'Hello' 
    else: 
     return a + b 


opts = {'left':fizz, 'right':foo, 'both':buzz} 

def main(): 
    left_or_right_growing = sys.argv[1] 
    crab = int(sys.argv[2]) 
    if left_or_right_growing == 'left': 
     opts['left'](crab,1,2) 

    elif left_or_right_growing == 'right': 
     opts['right'](crab,3,4) 

    elif left_or_right_growing == 'both': 
     opts['both'](crab,5,6) 

if __name__ == '__main__': 
    main() 

要測試if循環我只是將函數w ith一個簡單的if循環。正如你所看到的,即使是像這樣的簡單任務,函數方法也會更快。

+0

謝謝,我會給它一個射擊! – keynesiancross

0

你可以把這個代碼塊的功能,使它看起來更清潔:

if crab.rightclawCrusher == True: 
      crab.rightclaw_size = new_crushersize 
      if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth 
       crab.leftclaw_size = max(new_pincersize * crab.proportion_of_new_claw_thats_grownback()+adj, crab.leftclaw_size) 
     elif crab.rightclawCrusher == False: 
      crab.rightclaw_size = new_pincersize + adj 
      if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth 
       crab.leftclaw_size = max(new_crushersize * crab.proportion_of_new_claw_thats_grownback(), crab.leftclaw_size) 
+0

但它會加快代碼執行...? – keynesiancross

+0

@keynesiancross它不會讓它更快,我看到它的方式沒有太多你可以做得更快,除非你把字符串比較變成某種排序的枚舉 – Archmede