为什么发电机更快?

Can*_*ic3 2 python iterator generator

我知道生成器比迭代器更快.我也明白可以使用for循环语法实现生成器.例如:

    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
Run Code Online (Sandbox Code Playgroud)

这只是结果的一个例子:

myIter took 0.09234782
myGen(n) took 0.017847266
Run Code Online (Sandbox Code Playgroud)

因为这使用for循环语法,所以我不明白它是如何比迭代器更快.这个生成器使用迭代器,因为"for"循环是使用迭代器实现的.如果你计算时间,发电机一直更快.当生成器使用迭代器时,为什么会这样?

谢谢.

DSM*_*DSM 6

在你的代码中,myIter(n)实际上确实有效 - 它循环100次.

myGen(n)另一方面,只需构建发电机 - 就是这样.它不计入100.您所做的只是计算构建对象所需的时间,并且您以不可靠的方式对其进行计时.如果我们使用timeit(这里使用IPython使事情更简单):

>>> %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
Run Code Online (Sandbox Code Playgroud)

我们看到myGen(n)时间是独立的n,因为它没有做任何事情.事实上,我们可以看到您的代码从未以另一种方式执行:

>>> 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
Run Code Online (Sandbox Code Playgroud)

如果我们修复这个错误,然后尝试快速的方式来消耗生成器,我们得到类似的东西

>>> %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
Run Code Online (Sandbox Code Playgroud)

并且生成器版本较慢,通常是这种情况.