Thanks for trying this out.
When I saw your comments, I realized that the difference is due to a speed 
patch that we have her at CCP.
The test was run using current 2.5 python, with a patch applied, as attached 
this message.
The patch was written by me a few years back when I noticed that python spends 
enormous time during regular
run creating exceptions that then get discarded internally.  Most of the cost 
comes from FormatException
when it is generating AttributeErrors.
So, when I thought I was complaining about slow new objects, I was really 
showing off my cool optimization.

The problem is, it is difficult to generalize this to python in general.  I 
spent some time last year to
try to improve new-style classes, by adding ts fields and telling the exception 
system to "expect a certain
type of exception, and if it is raised, use PyErr_SetNone() instead of the 
PyErr_Format because I will
clear it anyway".  I had macros such as
PyErr_Expect(AttributeError);
attr = PyObject_GetAttr(o, a);
PyErr_Expect(0);
if (!attr)
        PyErr_Clear()

The problem was, I wasn't able to come up with a simple patch that showed 
consistent speed improvements
in the performance testsuite without showing some slowdowns in other places.

Running regular python code through a profiler, and especially code that relies 
much on the use of
__getattr__() to emulate attribute access, will show hideous amounts of time 
spent formatting
attribute exceptions that get thrown away.

Any thoughts on how to do this better?

And, for completeness, a new test run of this, using python25, first using the 
neutered patch version
(where I have set softfail=0 in the relevant places) and then with the patch 
active:

import timeit
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
"""
print timeit.Timer("d.foo", s).timeit()
print timeit.Timer("d.bar", s).timeit()
print timeit.Timer("d.a", s).timeit()

print timeit.Timer("d2.foo", s).timeit()
print timeit.Timer("d2.bar", s).timeit()
print timeit.Timer("d2.a", s).timeit()

patch neutered
1.35734336404
0.157773452422
0.0937950608722
1.48494915604
0.240154539405
0.186524222345

patch active:
0.352850669641
0.147599760073
0.0910020300097
1.4453737036
0.212842069748
0.203442097864


Cheers,

Kristján
> -----Original Message-----
> From: Nick Coghlan [mailto:[EMAIL PROTECTED]
> Sent: Wednesday, October 08, 2008 21:37
> To: Kristján Valur Jónsson
> Cc: Python-Dev
> Subject: Re: [Python-Dev] __getattr__ and new style classes
>
> 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:
>
> I can't reproduce those relative numbers using SVN trunk. Using your
> setup code (copied and pasted directly from your message to my
> interpreter session) I got the following numbers:
>
>

Attachment: speedpatch.rar
Description: speedpatch.rar

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to