Speed of Nested Functions & Lambda Expressions
Terry Jones
terry at jon.es
Thu Dec 6 17:37:11 EST 2007
[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
More information about the Python-list
mailing list