[Zope-dev] Re: hasattr implementation for Zope?
Tim Peters
tim.peters at gmail.com
Fri May 27 13:49:00 EDT 2005
[Paul Winkler]
>> But of course we don't do it because accessing globals in a method that
>> might be looped over is slow. Which, hopefully, will become a non-issue
>> some day (PEP 267, 268, 280).
[Jim Fulton]
> Note that in my version above, marker is a local rather than a global
> and gets looked up at local-variable speed.
Nope, it's a "cell" reference to an enclosing scope, and gets looked
up at cell-dereference speed. In my experience, that's generally a
bit slower than accessing a module global. That may have to do with a
quirk of MSVC's code generation; unsure.
Here's a little program that times it 3 ways:
"""
def lookup1(arg, _marker=object()):
return _marker
def lookup2():
_marker = object()
def lookup2(arg):
return _marker
return lookup2
lookup2 = lookup2()
_marker = object()
def lookup3(arg):
return _marker
from time import clock as now # s/clock/time/ on Linux
from itertools import repeat
for f in lookup1, lookup2, lookup3:
start = now()
for dummy in repeat(None, 1000000):
f(dummy)
finish = now()
print "%-8s %.6g" % (f.__name__, finish - start)
"""
Under WinXP Python 2.4.1, the global trick (lookup3) is consistently
fastest, and the lexical scope trick (lookup2) is consistently
slowest; this is typical output across 3 runs:
lookup1 0.427597
lookup2 0.450777
lookup3 0.404399
lookup1 0.423195
lookup2 0.471619
lookup3 0.405306
lookup1 0.42321
lookup2 0.448071
lookup3 0.405078
Note that lookup1 has the overhead of installing the default arg into
the locals on each call, which is an expense neither lookup1 nor
lookup3 endure.
measurement-never-agrees-with-anyone<wink>-ly y'rs - tim
More information about the Zope-Dev
mailing list