[Python-Dev] CALL_ATTR patch (was: 2.3b1 release)

Thomas Wouters thomas@xs4all.net
Fri, 18 Apr 2003 02:06:50 +0200

On Thu, Apr 17, 2003 at 10:59:56PM +0200, Thomas Wouters wrote:

> Unless I should make the shortcut depend on the actual value of
> tp_getattro, as in shortcut only if it actually is
> PyObject_GenericGetAttr ?

Well, I went ahead and did that, and uploaded the new patch to SF. The
result is somewhat annoying, but explainable: The patch is now 3% _slower_
than an unmodified Python, whereas the patch without support for newstyle
classes was a good 5% _faster_ than unmodified. This is both according to
PyBench (which doesn't use newstyle classes) and according to
'time timeit.py pass' (which does use newstyle classes.) Timing just
'x.foo()' where 'x' is a newstyle class instance is about 20% faster,
against 25-30% for oldstyle classes.

The overall slowdown is caused by the fact that the patch only treats
PyFunctions (functions written in Python) specially, and not PyMethodDescrs
(PyCFunctions wrapped in PyMethodDefs wrapped in a descriptor.) This is
because it would still need to instantiate a PyCFunctionObject (a PyObject
wrapper for a PyCFunction, which is just a C function-pointer) OR it would
need to do all interpretation of METH_* arguments and a bunch of
argument-preparing itself.

Another possible cause for the slowdown (but almost certainly not as
substantial as the type-with-C-function one) is calling an almost-method on
a newstyle class; a callable object that is an attribute of a type (or
instance of the type) but is not a PyFunction or PyMethodDescr. The way the
current mechanisms works, it would have to traverse the MRO and (possibly)
check the instance dict twice; first to determine that it's not a PyFunction
in _PyObject_Generic_getmethod() and then again in the regular run though
PyObject_GenericGetAttr(). Examples of this case would be staticmethods,
classmethods, and other callable objects as attributes. I do not believe
this is a substantial party though.

The slowdown can be fixed in two ways: handing PyMethodDescrs as well, in
_PyObject_Generic_getmethod(), or removing the double lookups. Hm, wait,
handling PyMethodDescrs may not be as tricky as I thought... hrm... I'll
look at it tomorrow, it's time for bed.

Thomas Wouters <thomas@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!