nested functions

Tim Peters tim_one at email.msn.com
Thu Feb 24 23:19:29 EST 2000


[Alexander V. Voinov]
> Please remind me, if there are any performance penalties in nesting
> functions ...

[Terry Reedy]
> The definition of a nested function is re-executed everytime the outer
> function is called.

[François Pinard]
> I would guess that the penalty is quite insignificant.  The function has
> been compiled once and for all with the rest, and the `def' "execution"
> is nothing a mere assignment of the function to a local variable.
> Isn't it?

Not quite that cheap, but it indeed isn't expensive.  The *code* object "has
been compiled once and for all", but a function object is layer of stuff
around the code object, and that layer gets rebuilt each time a 'def' is
executed.  Look up the implementation of the MAKE_FUNCTION opcode in ceval.c
for all the gory details.  In brief, a function object has to be allocated,
a pointer to the global namespace needs to be installed, and current
bindings for optional arguments (if any) need to be captured.

Example:

    adders = []
    for i in range(10):
        def adder(j, i=i):
            return j + i
        adders.append(adder)

    print adders[0](10), adders[9](10)

prints

    10 19

Had a fresh function object not been constructed each time, the correct
default value for the "i" argument could not have been captured.  The code
object capturing the body of "adder" was compiled only once, though, and is
shared among all "adder" instances.

All in all, it's probably about as expensive as creating (e.g.) two lists.

also-probably-about-as-cheap-ly y'rs  - tim






More information about the Python-list mailing list