nested functions

Duncan Booth duncan.booth at invalid.invalid
Thu Jun 15 06:56:43 EDT 2006


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&#4 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.



More information about the Python-list mailing list