Why are generators faster?

試著忘記壹切 提交于 2020-01-14 01:58:29

问题


I understand that generators are faster than iterators. I also understand that generators can be implemented using for loop syntax. For example:

    import time 


startT = time.time()


def myGen(n):
    for i in range(n):
        yield x         


def myIter(n):
    for i in range(n):
        pass

def main():
    n=100
    startT=time.time()
    myIter(n)
    print 'myIter took ', time.time() - startT

    startT=time.time()
    myGen(n)
    print 'myGen(n) took ', time.time() - startT

This is just one example of the results:

myIter took 0.09234782
myGen(n) took 0.017847266

Since this uses the for loop syntax, then I don't understand how it is faster than an iterator. This generator uses an iterator, because the "for" loop is implemented using an iterator. If you time these, the generator is consistently faster. Why is this, when the generator uses an iterator?

Thanks.


回答1:


In your code, myIter(n) actually does work -- it loops 100 times.

myGen(n), on the other hand, simply builds the generator -- and that's it. It doesn't count to 100. All you're doing is timing how long it takes to build the object, and you're timing it in an unreliable way. If we use timeit (here using IPython to make things simpler):

>>> %timeit myIter(100)
1000000 loops, best of 3: 1 µs per loop
>>> %timeit myGen(100)
10000000 loops, best of 3: 163 ns per loop
>>> %timeit myGen(10**1000)
10000000 loops, best of 3: 163 ns per loop

And we see that the myGen(n) time is independent of n, because it's not doing anything. In fact, we can see your code was never executed another way:

>>> list(myGen(100))
Traceback (most recent call last):
  File "<ipython-input-11-dd43d937402a>", line 1, in <module>
    list(myGen(100))
  File "<ipython-input-1-ba968e48e9fd>", line 3, in myGen
    yield x
NameError: name 'x' is not defined

If we fix this typo, and then try a fast way to consume the generator, we get something like

>>> %timeit myIter(100)
1000000 loops, best of 3: 1 µs per loop
>>> %timeit consume(myGen(100), 100)
100000 loops, best of 3: 3.44 µs per loop

and the generator version is slower, as is often the case.



来源:https://stackoverflow.com/questions/31766728/why-are-generators-faster

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!