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

时间:2015-10-18 18:54:53

标签: python performance for-loop while-loop coroutine

问题很简单,我有以下代码在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. 在表面看起来像循环正在进行增量边界检查,但据我所知,生成器或迭代器必须执行相同的量努力工作,所以如果完成的工作是一样的,为什么一个比另一个更快?
  2. 来自python generator wiki

    def generator(n):
        i = 0
        while i < n:
            yield i
            i += 1
    
    1. 在迭代器的情况下,通常会有一个成员函数被调用next,每次调用它时,它都将返回&#34;在iterable中的下一项&# 34; ,对我来说,这意味着很多函数调用,因此堆栈上的开销很大(更多的汇编代码来执行push和pop堆栈)并且基于我对coroutine(生成器)的了解,它试图通过创建一个新的分离堆栈(就像线程,它管理自己的程序计数器)来规避这一点,虽然它将不再处理大量的函数调用,它承担与线程相同的问题,即上下文切换。
      如果while循环没有面对我上面提到的任何开销,那么while循环如何更慢

1 个答案:

答案 0 :(得分:2)

我希望您所看到的性能差异与Python中定义的代码部分以及在解释器中定义的部分有关(在C中,对于cpython)。例如,在next循环情况下对for的调用将在C中处理,对于range或其他内置迭代,函数的实现将也是在C,所以它可能很快。另一方面,while循环的边界检查是一个Python表达式,需要在循环的每次传递中进行评估。 Python代码几乎总是比C代码慢,所以在某些情况下for循环可能比while循环更快,这并不太令人震惊。

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

唯一的例外可能是您已经对代码进行了大量分析,并发现特定循环是特定程序的最大性能瓶颈。如果是这种情况,请根据您的内心进行微观优化。