Why are these two functions different?
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 L L M
(when the "cursor" was on LOAD 4
it didn't look like a L L M
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