"optimizing out" getattr

Kent Johnson kent37 at tds.net
Thu Sep 15 16:04:31 EDT 2005


Peter Otten wrote:
> Daishi  Harada wrote:
> 
> 
>>I'd like to get the 'get2' function below to
>>perform like the 'get1' function (I've included
>>timeit.py results).
> 
>  
> 
>>labels = ('a', 'b')
>>def get1(x):
>>    return (x.a, x.b)
>>def mkget(attrs):
>>    def getter(x):
>>        return tuple(getattr(x, label) for label in attrs)
>>    return getter
>>get2 = mkget(labels)
>>
>># % timeit.py -s "import test" "test.get1(test.a)"
>># 1000000 loops, best of 3: 0.966 usec per loop
>># % timeit.py -s "import test" "test.get2(test.a)"
>># 100000 loops, best of 3: 4.46 usec per loop
> 
> No, you can just sit back and wait -- for Python 2.5:
> 
> $ cat attr_tuple25.py
> import operator
> 
> class A:
>     a = 1
>     b = 2
> 
> get2 = operator.attrgetter("a", "b")
> 
> def get1(x):
>     return x.a, x.b
> 
> $ python2.5 -m timeit -s'from attr_tuple25 import A, get1, get2' 'get1(A)'
> 1000000 loops, best of 3: 0.813 usec per loop
> $ python2.5 -m timeit -s'from attr_tuple25 import A, get1, get2' 'get2(A)'
> 1000000 loops, best of 3: 0.495 usec per loop

With Python 2.4 you can at least get closer to the hardcoded version:

F:\>type attr_tuple.py
import operator

class A:
    a = 1
    b = 2

getA = operator.attrgetter("a")
getB = operator.attrgetter("b")

def get2(x):
    return getA(x), getB(x)

def get1(x):
    return x.a, x.b

F:\>python -m timeit -s"from attr_tuple import A, get1, get2" "get1(A)"
1000000 loops, best of 3: 0.658 usec per loop

F:\>python -m timeit -s"from attr_tuple import A, get1, get2" "get2(A)"
1000000 loops, best of 3: 1.04 usec per loop

Kent



More information about the Python-list mailing list