Why is Python so slow ?- revisited.

Thomas Wouters thomas at xs4all.net
Mon Jun 19 13:14:58 EDT 2000


On Mon, Jun 19, 2000 at 06:52:50AM -0400, Bijan Parsia wrote:
> William Dandreta <wjdandreta at worldnet.att.net> wrote:

> > The biggest improvement came (about a factor of 6) when I changed the
> > replace(x,y) function in string with
> > joinfields(splitfields(x,y),''). Considering that this is exactly what the
> > replace function in string does, I was quite surprised at the results.
> > Essentially I reduced 3 nested function calls to 2.

> And that can make an enormous difference, particularly with earlier
> versions. Remember that many "simple function calls" in fact involve
> rather expensive polymorphic lookup and dispatching. In a tight loop
> this can get very painful (Python doens't have, I believe even in the
> latest versions, a method/function cache, so every lookup will go
> through the whole rigamarole each time).

Indeed. Such a cache would have to be invalidated whenever the function
object or one of the objects used to lookup the function, was altered (or
rather, 'touched'.) The dynamic nature of Python makes this quite
complicated, and probably quite expensive.

What's more, currently 'bound methods' (methods which have a 'self' to which
they apply) are created on demand -- the unbound method exists on the class,
but it has to be 'bound' to an instance before it can be used. This is done
each time you access the method, though CPython is being smart and you have
to try hard to actually see that ;-)

>>> class Minister:
...     def walk(self):
...             print "The minister walks silly."
... 
>>> cleese=Minister()

>>> cleese.walk is cleese.walk
0
>>> x,y=(cleese.walk, cleese.walk)
>>> id(x), id(y)
(134879776, 134879248)

Adding methods to the instance dictionary works, but breaks pickle (and
cPickle, and of course all code that does something to the parent class or
the objects' __bases__) and seems to incur penalties in other areas. (At
least according to pybench ;) But if you want to speed up your inner loop
even more, move methods into your local namespace. (Up to a certain limit,
for sure, but if you do a lot of methods in an inner loop you shouldn't be
too worried about performance in the first case.)

-- 
Thomas Wouters <thomas at xs4all.net>

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




More information about the Python-list mailing list