这里的新编码器;对不起,如果这个问题非常基本。
假设我有这样的功能:
def foo(a=True, b=False):
for i in range(1000000000):
if a:
obfuscate()
if b:
frobnicate()
这显然是低效的,因为我通过for循环评估每次迭代的if语句条件。什么是更优雅的方式来完成同样的事情?
编辑:当我试图最小化我的例子时,我认为我掩盖了过多的细节。我没有在这里捕获多个相互依赖关系。任何尚未参与讨论的人都应该明确指出。答案 0 :(得分:1)
查看您的代码,您并不表示a
或b
曾发生变化。因此,您可以在开始循环之前确定要调用哪些函数:
def foo(a=True, b=False):
for i in range(1000000):
if a:
obfuscate()
if b:
frobnicate()
变为:
def foo(a=True, b=False):
action = None
if a and b:
def f():
obfuscate()
frobnicate()
action = f
elif a:
action = obfuscate
elif b:
action = frobnicate
else:
return # Loop won't call any functions, skip it.
for i in range(1000000):
action()
我认为1000000
你的意思是很多次。" (实际上,在现代硬件上,1M实际上并非如此。)如果是这样,您可能希望将a and b
案例实际拆分为仅调用这两个函数的单独代码行,从而为您节省一些操作码拨打电话:
if a and b:
for i in range(1000000):
obfuscate()
frobnicate()
return
elif ...
答案 1 :(得分:0)
我将假设在每次迭代中都会出现a或b,在这种情况下,用if b:
替换elif b:
。这样,如果是a,则不检查b。
答案 2 :(得分:0)
我不会发现您编写的代码效率低下。此运行时为O(n)
,适用于您必须浏览列表的大多数情况。但是,有一项建议是,在检查elif
是否符合i
的情况时,您应该使用b
。如下:
def foo(a, b):
for i in range(1000):
<do things>
if a:
<do something>
elif b:
<do something slightly different>
编辑:如果a和b是固定参数,则可以使用:
def foo(a, b):
l = [i for i in range(1000)]
if a:
funcA(l)
elif b:
funcB(l)
答案 3 :(得分:0)
假设语义是正确的(我不知道&#34; *事物&#34;是否有任何副作用或没有,也不知道是否有任何类型的数据依赖),那么你可以移动{{ 1}}(循环不变)在循环之外
if
一般来说,编译器擅长在循环外移动循环不变量。
由于您使用的是python,我认为性能不是您的首要任务,因此我建议您坚持使用更具可读性的初始版本,并让编译器/解释器发挥其魔力并优化此功能对你而言。
答案 4 :(得分:-2)
你可能想要使用elif而不是第二个if if else中的条件仅在a为false时执行。除了代码优化之外,通常还要处理循环运行时的优化。如果条件对优化没有那么大的影响。
def foo(a, b):
for i in range(1000):
<do things>
if a:
for i in range(1000):
<do something>
if b:
for i in range(1000):
<do something slightly different>