python 中的生成器是否比 while 循环更快?

Is generator faster than while loop in python?

问题很简单,我有以下代码在python2中做同样的事情:

for _ in range(n): # or xrange(),they have similar performance according to my test
    pass

i = 0
while i < n:
    i+=1
    pass

for循环比while循环快,当n = 1000000时,每个大约需要0.105544和0.2389421

  1. 表面上看起来 while 循环正在执行 增量 边界检查 ,但据我所知,生成器或者迭代器必须执行相同数量的艰苦工作,所以如果完成的工作相同,为什么一个比另一个快?

来自 python generator wiki

def generator(n):
    i = 0
    while i < n:
        yield i
        i += 1
  1. 在迭代器的情况下,通常有一个成员函数接下来被调用,每次调用都会return "next item in the iterable",对我来说这意味着 很多 函数调用,因此堆栈上的巨大开销(更多的汇编代码用于压入和弹出堆栈)和基于根据我对协程(生成器)的了解,它试图通过创建一个新的分离堆栈来规避这个问题(就像线程一样,它管理自己的程序计数器),虽然它不再处理大量的函数调用,但它有同样的问题作为线程,即上下文切换.
    的开销 当 while 循环没有遇到我上面提到的任何开销时,它怎么会变慢

我预计您看到的性能差异与代码的哪些部分在 Python 中定义以及在解释器内部定义(在 C 中,对于 cpython)有关。例如,在 for 循环情况下对 next 的调用将在 C 中处理,而对于 range 或其他内置可迭代对象,函数的实现将也在 C 中,所以它可能非常快。另一方面,while 循环的边界检查是一个 Python 表达式,需要在循环的每次通过时对其求值。 Python 代码几乎总是比 C 代码慢,因此 for 循环在某些情况下可能比 while 循环更快并不令人震惊。

但是请注意,这两种循环可能比您在其中进行的任何有用工作都要快得多。几乎不值得将精力集中在像这样的不同类型循环之间的非常小的性能差异上,而不是像算法的复杂性或数据结构的效率这样的大问题上。

唯一的例外可能是,如果您对代码进行了大量分析并发现特定循环是特定程序的最大性能瓶颈。如果是这样,请根据自己的喜好进行微优化。