[Python-Dev] Comparing closures and arguments (was Re: Scoping vs augmented assignment vs sets (Re: 'fast locals' in Python 2.5)

Phillip J. Eby pje at telecommunity.com
Wed Jun 14 20:52:47 CEST 2006

At 11:26 AM 6/14/2006 -0700, Josiah Carlson wrote:
>Ok, so here's a bit of a benchmark for you.
>     def helper(x,y):
>         return y
>     def fcn1(x):
>         _helper = helper
>         y = x+1
>         for i in xrange(x):
>             y = _helper(x,y)
>     def fcn2(x):
>         y = x+1
>         def _helper(x):
>             return y
>         for i in xrange(x):
>             y = _helper(x)
>Can you guess which one is faster?  I guessed, but I was wrong ;).
> >>> x = 1000000
> >>> min([fcn1(x) for i in xrange(10)]), min([fcn2(x) for i in xrange(10)])
>(0.53200006484985352, 0.59299993515014648)
>It turns out that passing two arguments to a helper function is actually
>faster than passing one argument and pulling a second out of an
>enclosing scope.

That claim isn't necessarily supported by your benchmark, which includes 
the time to *define* the nested function 10 times, but calls it only 45 
times!  Try comparing fcn1(1000) and fcn2(1000) - I suspect the results 
will be somewhat closer, but probably still in favor of fcn1.

However, I suspect that the remaining difference in the results would be 
due to the fact that the interpreter loop has a "fast path" function call 
implementation that doesn't work with closures IIRC.  Perhaps someone who's 
curious might try adjusting the fast path to support closures, and see if 
it can be made to speed them up without slowing down other "fast path" calls.

More information about the Python-Dev mailing list