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