我目前有一种令人讨厌的代码块,我正在编写一个模拟螃蟹生长的程序(令人兴奋的东西.....)。该程序后来被更大的模拟吸收,因此代码的速度很重要。我最慢的代码块之一包含这个讨厌的分支逻辑。我希望有人能想出一种方法来提高效率......
对于上下文,这段代码基本上是这样说的:"我是否正在重生爪子?如果是这样的话。如果左/右爪重新生长,它是主导还是非主导手?鉴于此,请应用此数字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)
答案 0 :(得分: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
然后当我使用你的方法并用它自己的if循环替换函数时:
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循环,我只需用一个简单的if
循环替换函数。正如您所看到的,即使是这样的简单任务,函数方法也会更快。
答案 1 :(得分: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)