python3性能:循环使用range()Vs plain old while()

bad*_*mad 0 python performance range python-3.x

在Python3中,我发现如果我替换一个

对于范围内的i(n):

声明

而我<n:

我获得了显着的运行时增益 我的循环本身并没有多余的基础算术运算.

任何指向我为什么看到这种行为的指针?

编辑:n的范围是K,10K,12K等10s.我观察到的时间是.19s为12K,.12s为10K with while循环.使用'while'循环,我看到.11s为12K,.08s为10K.这是我的计划:

target = 0
i = 1
#for i in range(1, n+1):
while i < n+1:
    target += i * (2 ** (i - 1)) + (i * (i + 1))//2
    i += 1

return target % (10 ** 9 + 7)
Run Code Online (Sandbox Code Playgroud)

Sha*_*ger 5

range涉及少量的固定开销(查找range,首先在全局变量中,然后在内置函数中,然后是泛型函数调用分配的成本,以及分配/初始化对象); 如果n足够小,它将不会减少每个循环的成本:

In [1]: %%timeit -r5 n = 3
   ...: for i in range(n):
   ...:     pass
   ...:
365 ns ± 15.1 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

In [2]: %%timeit -r5 n = 3
   ...: i = 0
   ...: while i < n:
   ...:     i += 1
   ...:
252 ns ± 16.9 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)
Run Code Online (Sandbox Code Playgroud)

但是当n达到中等大小时,每件物品的开销减少会带来回报:

In [3]: %%timeit -r5 n = 10
   ...: for i in range(n):
   ...:     pass
   ...:
461 ns ± 18.1 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

In [4]: %%timeit -r5 n = 10
   ...: i = 0
   ...: while i < n:
   ...:     i += 1
   ...:
788 ns ± 73.6 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)
Run Code Online (Sandbox Code Playgroud)

range 涉及更高的固定成本,但更低的单项成本,这就是全部.

  • @DeepSpace:是的.`range`(在传递小的int缓存边界之后)必须创建实际的对象,并且必须在缓存之前查找它们; `repeat`没有,这节省了一点时间.节省的费用并非完全无关紧要(对于'n = 10'情况,我的时序测量值为319 ns±39.6 ns),但它们并不像'range`与手动`while`循环一样极端,并且需要导入(其本身花费超过一微秒,因此至少节省了前几次使用的节省)使得它不是一个自动选择(特别是如果`i`可能用于某些东西). (2认同)