Duncan Booth wrote: > Fredrik Lundh wrote: > > > George Sakkis wrote: > > > >> It shouldn't come as a surprise if it turns out to be slower, since > >> the nested function is redefined every time the outer is called. > > > > except that it isn't, really: all that happens is that a new function > > object is created from prebuilt parts, and assigned to a local > > variable. it's not slower than, say, a method call. > > > It looks to be somewhat faster than a method call: > > C:\temp>\python24\lib\timeit.py -s "import t" "t.testMethod(t.instance, > 42)" > 1000 loops, best of 3: 1.58 msec per loop > > C:\temp>\python24\lib\timeit.py -s "import t" "t.testMethod2(t.instance, > 42)" > 100 loops, best of 3: 1.61 msec per loop > > C:\temp>\python24\lib\timeit.py -s "import t" "t.testNested(t.instance, > 42)" > 1000 loops, best of 3: 1.06 msec per loop > > C:\temp>\python24\lib\timeit.py -s "import t" "t.testNested2(t.instance, > 42)" > 1000 loops, best of 3: 1.08 msec per loop > > C:\temp>\python24\lib\timeit.py -s "import t" "t.testNested3(t.instance, > 42)" > 1000 loops, best of 3: 1.13 msec per loop > > C:\temp>\python24\lib\timeit.py -s "import t" "t.testNested4(t.instance, > 42)" > 1000 loops, best of 3: 1.23 msec per loop > > > --------- t.py ------------- > class C: > def m1(self): > return 42 > > def m2(self, x): > return x > > instance = C() > > def testMethod(instance,x): > n = 0 > while n < 100000: > n += instance.m1() > > def testMethod2(instance, x): > n = 0 > while n < 100000: > n += instance.m2(x) > > def testNested(instance, x): > def m1(): > return 42 > n = 0 > while n < 100000: > n += m1() > > def testNested2(instance, x): > def m2(): > return x > n = 0 > while n < 100000: > n += m2() > > def testNested3(instance, x): > def m2(y): > return y > n = 0 > while n < 100000: > n += m2(x) > > def testNested4(instance, x): > def m2(y): > return x > n = 0 > while n < 100000: > n += m2(x) > > ---------------------------- > > The differences between the nested function calls show how difficult it can > be guessing what will be faster: #3 show that all, else being equal, > accessing the closure is much slower than accessing a parameter, but #2 > shows that not passing any parameters to the nested function more than > compensates for the single slow closure access.
It would also be interesting to add unnested versions of m1(), m2() (functions, not methods) to the comparison. George -- http://mail.python.org/mailman/listinfo/python-list