On Sat, Mar 25, 2017 at 6:35 AM, Tim Chase <python.l...@tim.thechases.com> wrote: > $ python3 > Python 3.4.2 (default, Oct 8 2014, 10:45:20) > [GCC 4.9.1] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> from dis import dis >>>> def f(x): > ... return x * 1024 * 1024 > ... >>>> dis(f) > 2 0 LOAD_FAST 0 (x) > 3 LOAD_CONST 1 (1024) > 6 BINARY_MULTIPLY > 7 LOAD_CONST 1 (1024) > 10 BINARY_MULTIPLY > 11 RETURN_VALUE > > Is there any reason that Python doesn't do the constant folding of > 1024 * 1024? Especially as it does constant folding if the order is > reversed: > >>>> def f(x): > ... return 1024 * 1024 * x > ... >>>> dis(f) > 2 0 LOAD_CONST 2 (1048576) > 3 LOAD_FAST 0 (x) > 6 BINARY_MULTIPLY > 7 RETURN_VALUE > > > I'm cool with defining things as a constant and using those instead > or front-loading my constants in my expressions, but the disparity > struck me as a little odd. Any insights on the reasons/motivations > for one and not the other?
The first example is: (x * 1024) * 1024 The second is: (1024 * 1024) * x The first one can't be constant-folded without a semantic change (Python can't know that x will always be a number, even if you do). Suggestion: Use a different operator, which binds more tightly. >>> def f(x): ... return x * 2**20 ... >>> dis(f) 2 0 LOAD_FAST 0 (x) 2 LOAD_CONST 3 (1048576) 4 BINARY_MULTIPLY 6 RETURN_VALUE Since this evaluates as x * (2**20), it can be constant-folded. ChrisA -- https://mail.python.org/mailman/listinfo/python-list