在下面的代码中,为什么Python不能编译f2
为相同的字节码f1
?
有理由不去吗?
>>> def f1(x):
x*100
>>> dis.dis(f1)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (100)
6 BINARY_MULTIPLY
7 POP_TOP
8 LOAD_CONST 0 (None)
11 RETURN_VALUE
>>> def f2(x):
x*10*10
>>> dis.dis(f2)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (10)
6 BINARY_MULTIPLY
7 LOAD_CONST 1 (10)
10 BINARY_MULTIPLY
11 POP_TOP
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
Nic*_*tin 71
这是因为x
可能有一种__mul__
副作用的方法. x * 10 * 10
调用__mul__
两次,而x * 100
只调用一次:
>>> class Foo(object):
... def __init__ (self):
... self.val = 5
... def __mul__ (self, other):
... print "Called __mul__: %s" % (other)
... self.val = self.val * other
... return self
...
>>> a = Foo()
>>> a * 10 * 10
Called __mul__: 10
Called __mul__: 10
<__main__.Foo object at 0x1017c4990>
Run Code Online (Sandbox Code Playgroud)
自动折叠常量只调用__mul__
一次可能会改变行为.
您可以通过重新排序操作来获得所需的优化,使得常量首先相乘(或者,如注释中所述,使用括号将它们分组,使得它们仅在一起操作,无论位置如何),从而明确表示您的渴望折叠发生:
>>> def f1(x):
... return 10 * 10 * x
...
>>> dis.dis(f1)
2 0 LOAD_CONST 2 (100)
3 LOAD_FAST 0 (x)
6 BINARY_MULTIPLY
7 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
Wes*_*ley 17
Python 从左到右评估表达式.对于f2()
,这意味着它将首先评估x*10
然后将结果乘以10.尝试:
尝试:
def f2(x):
10*10*x
Run Code Online (Sandbox Code Playgroud)
这应该优化.
归档时间: |
|
查看次数: |
1249 次 |
最近记录: |