Generators vs. Functions?
Duncan Booth
duncan.booth at invalid.invalid
Sun Feb 5 05:05:22 EST 2006
Steven D'Aprano wrote:
>>>> t1.timeit()
> 0.63980388641357422
...
>>>> t2.timeit()
> 0.82081794738769531
>
> So on the basis of my tests, there is a small, but significant speed
> advantage to _calling_ a function versus _resuming_ a generator.
I get the same, but the difference is much less on my system:
>>> min(t1.timeit() for i in range(3))
0.43929577641858941
>>> min(t2.timeit() for i in range(3))
0.46473169075954956
You missed though what is perhaps a more representative case. Generators
have state, so for a fair comparison you need to restore some state. I
think a fairer comparison is:
>>> t5 = timeit.Timer(stmt="func.next()", setup=
"""class K:
pass
def next(self):
return 1
func = K()
""")
>>>
>>> min(t5.timeit() for i in range(3))
0.58508302032805659
The method call is slower than the generator resumption and that is without
even accessing any of the saved state. If you do access the saved state the
generator runs at about the same speed as the original (local variable
access is about as fast as accessing a constant), but the method slows down
even more:
>>> t6 = timeit.Timer(stmt="gen.next()", setup=
"""def g(n):
while 1: yield n
gen = g(42)
""")
>>> min(t6.timeit() for i in range(3))
0.46405506845144373
>>> t7 = timeit.Timer(stmt="func.next()", setup=
"""class K:
def __init__(self, n):
self.n = n
def next(self):
return self.n
func = K(42)
""")
>>> min(t7.timeit() for i in range(3))
0.67426781895460408
More information about the Python-list
mailing list