python优化分支逻辑
我目前正在为一个模拟螃蟹生长的程序编写一段令人讨厌的代码(令人兴奋的东西…)。这个程序后来被一个更大的模拟所吸收,所以代码的速度很重要。我最慢的代码块之一包含这种讨厌的分支逻辑。我希望有人能想出一个更有效的方法 在上下文中,这段代码基本上是这样说的:“我是在再生一只爪吗?如果是,是哪只。如果左/右爪正在再生,是主爪还是非主爪?鉴于此,应用这个数字xyz”python优化分支逻辑,python,Python,我目前正在为一个模拟螃蟹生长的程序编写一段令人讨厌的代码(令人兴奋的东西…)。这个程序后来被一个更大的模拟所吸收,所以代码的速度很重要。我最慢的代码块之一包含这种讨厌的分支逻辑。我希望有人能想出一个更有效的方法 在上下文中,这段代码基本上是这样说的:“我是在再生一只爪吗?如果是,是哪只。如果左/右爪正在再生,是主爪还是非主爪?鉴于此,应用这个数字xyz” 如果左或右增长=='left': 如果crab.RightClawCruser==真: crab.RightClawl\u尺寸=新的\u压碎尺
如果左或右增长=='left':
如果crab.RightClawCruser==真:
crab.RightClawl\u尺寸=新的\u压碎尺寸
如果crab.moltnumber_for_claw_remove_left1。或pro_right>1:
打印('TRANFORM:pro_left:'+str(pro_left)+'pro_right:'+str(pro_right))
如果crab.RightClawCruser==真:
如果crab.moltnumber_for_claw_remove_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)
如果crab.rightclawler==True:
crab.RightClawl\u尺寸=新的\u压碎尺寸
如果crab.moltnumber_for_claw_remove_left
根据前面的人所说,您可以为三个条件之后出现的所有嵌套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
循环。正如您所看到的,即使对于这样一个简单的任务,函数方法也会更快。将elif==False:
更改为just否则:
如果唯一的可能性是True
和False
。是否有某种方法可以缓存所有测试的结果,这样您就不必每次都重复它们了?如果它们是动态的,那么周期性地改变(即,不像我总是用右手的人那样)显然不是一直都是一样的,但是如果你能在数据结构中缓存决策树的结果,使用Dmitry答案中的函数式,那就省去了大量的跳跃。@keynesiancross它不会使它更快,在我看来,没有什么可以做的,除非将字符串比较转换为某种枚举
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()