[Python-Dev] __getattr__ and new style classes

Steven D'Aprano steve at pearwood.info
Thu Oct 9 00:35:46 CEST 2008


On Thu, 9 Oct 2008 06:27:06 am Kristján Valur Jónsson wrote:
> Hello there.
> I've just noticed what I consider a performance problem:
> Using new style classes to provide attribute-like access using
> __getattr__ is considerably slower than old style classes:  Observe:
>
> s = """
> class dude:
>         def bar(self):pass
>         def __getattr__(self, a): return a
> class dude2(object):
>         def bar(self):pass
>         def __getattr__(self, a): return a
> d = dude()
> d2 = dude2()
> d.a = d2.a = 1
> """
> timeit.Timer(´d.foo´, s).timeit()
> >0.32979211801421116
>
> timeit.Timer(´d2.foo´, s).timeit()
> > 1.1119853719342245

Not only don't I observe the same results as you, I'm afraid I can't 
even get your code to run. I get a SyntaxError from the funny quotes 
you're using: ´d.foo´ instead of 'd.foo' or "d.foo".

Also, I trust you know enough not to pay too much attention to a single 
test result? Timing results are notoriously subject to interference 
from external processes.

Finally, when reporting performance problems, it will be VERY helpful to 
report the version and platform you are using. There's no point in 
having people looking for a slow-down in Python 2.6 if you're actually 
using Python 2.3 (say).

Anyway, for the record here are my results for Python 2.5. I don't 
believe the differences are significant.

>>> min(Timer('d.foo', s).repeat())
1.9228429794311523
>>> min(Timer('d2.foo', s).repeat())
2.1040639877319336

>>> min(Timer('d.bar', s).repeat())
0.68272304534912109
>>> min(Timer('d2.bar', s).repeat())
0.41949796676635742

>>> min(Timer('d.a', s).repeat())
0.45727396011352539
>>> min(Timer('d2.a', s).repeat())
0.59516501426696777


-- 
Steven


More information about the Python-Dev mailing list