Take a look at this:
>>> def f():
... return (2+3)*4
...
>>> dis(f)
2 0 LOAD_CONST 5 (20)
3 RETURN_VALUE
Evidently, the compiler has pre-evaluated (2+3)*4
, which makes sense.
Now, if I simply change the order of the operands of *
:
>>> def f():
... return 4*(2+3)
...
>>> dis(f)
2 0 LOAD_CONST 1 (4)
3 LOAD_CONST 4 (5)
6 BINARY_MULTIPLY
7 RETURN_VALUE
The expression is no longer fully pre-evaluated! What is the reason for this? I am using CPython 2.7.3.
In the first case the unoptimized code is LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY
and in the second case it's LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLY
. The pattern matcher in fold_binops_on_constants()
must handle the first ADD
ok (replacing LOAD LOAD ADD
with LOAD
) and then follows on to do the same thing to MULTIPLY
. In the second case by the time the ADD
(now the second argument to MULTIPLY
instead of the first) is turned into a constant the scanner is too far ahead to see LLM
(when the "cursor" was on LOAD 4
it didn't look like a LLM
yet).
Looks like this issue was patched in Python 3.3, as can be seen here .
>>> def f():
... return (2+3)*4
...
>>> dis(f)
2 0 LOAD_CONST 5 (20)
3 RETURN_VALUE
>>> def f():
... return 4*(2+3)
...
>>> dis(f)
2 0 LOAD_CONST 5 (20)
3 RETURN_VALUE
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.