Why is Python so slow ?- revisited.

Bijan Parsia bparsia at email.unc.edu
Mon Jun 19 20:47:09 EDT 2000


Thomas Wouters <thomas at xs4all.net> wrote:

> 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.

I'd love to hear more about why this would be the case. (Mere
"dynamicness" can't be it: Smalltalk is a s dynamic and most
implementations make quite effective use of various sorts of cache. So,
if your contention is correct, there must be some *special* aspect of
Python's dynamic nature that makes it' *especially* resistent. Note that
I am *very* skeptical about the existence of such a special aspect, but
I am quite willing to be enlightened! Merely being "more dynamic" or "so
very dynamic" which is what I usual read, doesn't cut any mustard.

Indeed, as my bet is that the majority of the time, in the majority of
code, things are quite "hands off" (i.e., no touching :)), I would be
surprised that this would prove a problem. In inner loops, indeed, it
could be quite effective, and would be no different than *manually*
copying the function to the local--a move, I hope you agree, can provide
a substantial speedup.

I confess to not being an expert in these matters, but I don't know I
understand why the *whole* cache would have to be invalidated if one
function object were "touched". Er..in mere other words...More please!
:)

> 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 ;-)

Hmm. Ok. I think. Maybe. Why it has to be do each time one accesses the
*instance*'s method I find a tad confusing. I mean ok, you change the
class def, you'll want to update the instances. But surely it's ok to
make class updates more expensive than method access?

> >>> 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)

Ewww! :) But *why* do this? walk hasn't changed. It's surely
determinable that it hasn't changed over the course of x,y=(cleese.walk,
cleese.walk), yes?

[snip]

I'll work on digesting the rest. Thanks.

-- 
Bijan Parsia
http://monkeyfist.com/
...among many things.



More information about the Python-list mailing list