[Python-Dev] closure semantics

Alex Martelli aleaxit at yahoo.com
Sat Oct 25 09:37:57 EDT 2003


On Wednesday 22 October 2003 07:57 pm, Guido van Rossum wrote:
   ...
> > def accgen(n):
> >    def acc(i):
> >      global n in accgen
> >      n += i
> >      return n
> >    return acc
> >
> > particulary more compelling than:
> >
> > class accgen:
> >    def __init__(self, n):
> >      self.n = n
> >
> >    def __call__(self, i):
> >      self.n += i
> >      return self.n
>
> Some people have "fear of classes".  Some people think that a
> function's scope can be cheaper than an object (someone should time
> this).

I need to simulate the "rebinding name in outer scope" with some kind of
item or attribute, of course, but, given this, here comes:

given this b.py:

def accgen_attr(n):
    def acc(i):
        acc.n += i
        return acc.n
    acc.n = n
    return acc

def accgen_item(n):
    n = [n]
    def acc(i):
        n[0] += i
        return n[0]
    return acc

class accgen_clas(object):
    def __init__(self, n):
        self.n = n
    def __call__(self, i):
        self.n += i
        return self.n

def looper(accgen, N=1000):
    acc = accgen(100)
    x = map(acc, xrange(N))
    return x

I measure:

[alex at lancelot ext]$ timeit.py -c -s'import b' 'b.looper(b.accgen_attr)'
1000 loops, best of 3: 1.86e+03 usec per loop

[alex at lancelot ext]$ timeit.py -c -s'import b' 'b.looper(b.accgen_item)'
1000 loops, best of 3: 1.18e+03 usec per loop

[alex at lancelot ext]$ timeit.py -c -s'import b' 'b.looper(b.accgen_clas)'
100 loops, best of 3: 2.1e+03 usec per loop

So, yes, a function IS slightly faster anyway (accgen_attr vs accgen_clas),
AND simulating outer-scope-rebinding with a list item is somewhat faster
than doing so with an attr (a class always uses an attr, and most of its
not-too-terrible performance handicap presumably comes from that fact).

I just don't think such closures would typically be used in bottlenecks SO
tight that a 10%, or even a 40%, extra overhead are going to be crucial.
So, I find it hard to get excited either way by this performance issue.


Alex




More information about the Python-Dev mailing list