[Referring to the thread at http://mail.python.org/pipermail/python-list/2007-October/463348.html with apologies for top posting (I don't have the original mail)]
Duncan Booth wrote: > You can use Python's bytecode disassembler to see what actually gets > executed here: > > >>> def fn_outer(v): > a=v*2 > def fn_inner(): > print "V:%d,%d" % (v,a) > > fn_inner() > > >>> import dis > >>> dis.dis(fn_outer) > 2 0 LOAD_DEREF 1 (v) [snip] > When you execute the 'def' statement, the two scoped variables a and v > are built into a tuple on the stack, the compiled code object for the > inner function is also pushed onto the stack and then the function is > created by the 'MAKE_CLOSURE' instruction. This is then stored in a > local variable (STORE_FAST) which is then loaded and called. > > So the function definition is pretty fast, BUT notice how fn_inner is > referenced by STORE_FAST/LOAD_FAST whereas a and v are referenced by > LOAD_DEREF/STORE_DEREF and LOAD_CLOSURE. > > The code for fn_inner also uses LOAD_DEREF to get at the scoped > variables: I'd like to understand what it is that triggers the use of LOAD/STORE_DEREF versus LOAD/STORE_FAST. This seems dependent on how fn_inner above uses the a and v variables. If I change the print "V:%d,%d" % (v,a) line to be something like (a, v) = (v, a) or do other simple uses and assignments to a and v, LOAD/STORE_FAST is used. It seems that it's the use of print (in this case) that triggers the use of LOAD/STORE_DEREF in the bytecode. Can anyone shed more light on what in general causes the switch to LOAD/STORE_DEREF? I find it a bit disconcerting that the simple presence of a nested function (even if never used) may trigger significant slowdown in variable access for the rest of the code in the containing function. I'd be happy to know how/when this happens. I know I probably shouldn't care, but I do. Thanks, Terry Jones -- http://mail.python.org/mailman/listinfo/python-list