
On 6/1/2011 1:32 PM, Bruce Leban wrote:
def f(x,y): x += y dis.dis(f) 2 0 LOAD_FAST 0 (x) 3 LOAD_FAST 1 (y) 6 *INPLACE_ADD* 7 STORE_FAST 0 (x) 10 LOAD_CONST 0 (None) 13 RETURN_VALUE def g(x,y): x = x + y
dis.dis(g) 2 0 LOAD_FAST 0 (x) 3 LOAD_FAST 1 (y) 6 *BINARY_ADD* 7 STORE_FAST 0 (x) 10 LOAD_CONST 0 (None) 13 RETURN_VALUE
(In 3.2, one no longer needs to wrap code in a function to dis it. see below.) To see the 'calculate the source/target just once instead of twice' part, you need a source/target that actually requires calculation.
from dis import dis dis('x[i] = x[i] + 1') 1 0 LOAD_NAME 0 (x) 3 LOAD_NAME 1 (i) 6 BINARY_SUBSCR 7 LOAD_CONST 0 (1) 10 BINARY_ADD 11 LOAD_NAME 0 (x) 14 LOAD_NAME 1 (i) 17 STORE_SUBSCR 18 LOAD_CONST 1 (None) 21 RETURN_VALUE
dis('x[i] += 1') 1 0 LOAD_NAME 0 (x) 3 LOAD_NAME 1 (i) 6 DUP_TOP_TWO 7 BINARY_SUBSCR 8 LOAD_CONST 0 (1) 11 INPLACE_ADD 12 ROT_THREE 13 STORE_SUBSCR 14 LOAD_CONST 1 (None) 17 RETURN_VALUE
Even this does not show much difference as the dup and rotate substitute for two loads but do not actually save any calculation. However,
dis('a.b[c+d] = a.b[c+d] + 1') 1 0 LOAD_NAME 0 (a) 3 LOAD_ATTR 1 (b) 6 LOAD_NAME 2 (c) 9 LOAD_NAME 3 (d) 12 BINARY_ADD 13 BINARY_SUBSCR 14 LOAD_CONST 0 (1) 17 BINARY_ADD 18 LOAD_NAME 0 (a) 21 LOAD_ATTR 1 (b) 24 LOAD_NAME 2 (c) 27 LOAD_NAME 3 (d) 30 BINARY_ADD 31 STORE_SUBSCR 32 LOAD_CONST 1 (None) 35 RETURN_VALUE
dis('a.b[c+d] += 1') 1 0 LOAD_NAME 0 (a) 3 LOAD_ATTR 1 (b) 6 LOAD_NAME 2 (c) 9 LOAD_NAME 3 (d) 12 BINARY_ADD 13 DUP_TOP_TWO 14 BINARY_SUBSCR 15 LOAD_CONST 0 (1) 18 INPLACE_ADD 19 ROT_THREE 20 STORE_SUBSCR 21 LOAD_CONST 1 (None) 24 RETURN_VALUE
The latter has the same dup-rotate in place of a bit more calculation. The same would be true of, for instance, f(a).b. -- Terry Jan Reedy