Python's documentation表明for
语句实际上是语法糖,它掩盖了迭代器和可迭代对象概念的复杂性。如果是这样,则意味着以下两个功能相同:
def for_loop(seq):
for i in seq:
i
和
def while_loop(seq):
iseq = iter(seq)
_loop = True
while _loop:
try:
i = next(iseq)
except StopIteration:
_loop = False
else:
i
请注意,为了使for
语句的性能更好,我将循环的主体尽可能地简化,因此避免了调用print
(或类似函数)
以下是在IPython中测量这些功能的性能后的结果:
In [43]: %timeit for_loop(range(1000))
22.9 µs ± 356 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [44]: %timeit while_loop(range(1000))
49.9 µs ± 825 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [45]: %timeit for_loop(range(100000))
2.63 ms ± 43.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [46]: %timeit while_loop(range(100000))
5.16 ms ± 69.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
for
语句实际上是while
循环的两倍(在传递长列表而不是长迭代器时,观察到1.6的差异要小一些)。对于len(seq)
的值范围,性能差异是恒定的。我还观察到,当我使用dis
模块反汇编它们时,这些函数的字节码有所不同。
总结:Python的文档指出,使用for
语句时,Python实际上将其作为while_loop
的封面运行。有人可以用Pythoneer解决性能差异和特殊性的问题吗?它的根源是什么(CPython优化,...)?
答案 0 :(得分:1)
一些注意事项:
for
实际上只是while
的语法加糖,这意味着它实际上具有相同的实现。不同的实现可能具有非常不同的性能。 for
和while
确实有不同的实现。例如,请参见https://github.com/python/cpython/blob/ee40e4b8563e6e1bc2bfb267da5ffc9a2293318d/Python/compile.c compiler_while
和compiler_for
for
对范围进行了某种优化。当不是用range(1000000)
来计时两个功能时,我用np.random.rand(1000000)
来计时它们时,间隔从笔记本电脑上的3倍(24毫秒对73毫秒)下降到50%(101毫秒对155毫秒)。