[Python-Dev] __getattr__ and new style classes

Kristján Valur Jónsson kristjan at ccpgames.com
Wed Oct 8 21:27:06 CEST 2008

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()
timeit.Timer(´d2.foo´, s).timeit()
> 1.1119853719342245

The overhead is almost 3 times as high.  I imagine that this is because new style classes must search further and harder before giving up and going to __getattr__.
For the bound method the difference is less:

timeit.Timer(´d.bar´, s).timeit()
> 0.11835480370018558
timeit.Timer(´d2.bar´, s).timeit()
> 0.17820851929263881

For fun, I also tested regular attributes, and see:

timeit.Timer(´d.a´, s).timeit()
> 0.069161394202183146
timeit.Timer(´d2.a´, s).timeit()
> 0.17966275972594303

I'm surprised that accessing instance attributes like this is twice as slow using new style classes.

Any thoughts on this?
We are using a lot of low-level attribute access magic in EVE and so it would appear that we are best served by sticking with old-style classes.  But these are going away eventually, so what to do?
Where is this extra overhead coming from?
And oh, it is no use using __getattribute__ instead, since it will always involve calls to object.__getattribute__ and become very slow.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20081008/d4811484/attachment.htm>

More information about the Python-Dev mailing list