id() collisions on bound methods [was: metaclass and customization with parameters]
Alex Martelli
aleaxit at yahoo.com
Wed Oct 6 06:09:31 EDT 2004
Jeff Epler <jepler at unpythonic.net> wrote:
> Perhaps someone could devise a metaclass that does bound method caching.
> In a few situations, it might be worth having, but I'm not sure if in
> those situations a little
> c.f = c.f
> in __init__, or manual hosting like 'f=c.f' is not just as appropriate.
You may well be right, but people to have a reasonable aversion to
manual hoisting and similar optimization-oriented boilerplate -- yeah,
it IS simpler to implement than having it happen behind the scene, but
it clutters up applications.
The metaclass you mention could wrap every function in a specialized
descriptor (which would have to know the corresponding name, given at
init time -- __get__ isn't told the name, a design error IMHO) whose
__get__ delegates to the function's and then caches the result in the
instance.
Measurement suggests that with Python 2.3, normal method calls (to a
'def f(): pass' method) take (on my old machine) 0.91 microseconds/call
without precautions; calls with manual caching as you suggest take 0.86;
calls with an automatic caching descriptors, 0.87. For once, 2.4 is
minimally slower -- 0.96, 0.90, 0.91. Considering that a typical method
will do more work than just 'pass', doesn't sound like an optimization
worth pursuing, alas.
_Hoisting_, otoh (the f=c.f idea) takes the time down to 0.66 for 2.3,
0.69 for 2.4 -- now THAT is helpful. Unfortunately I don't know of an
easy way to automate that. Maybe Hettinger's recipe on a decorator for
automatic hoisting of globals could be tweaked for the purpose...?
Alex
More information about the Python-list
mailing list