gpt4 book ai didi

python - 为什么 yield 生成的生成器比 xrange 生成的生成器快?

转载 作者:太空狗 更新时间:2023-10-29 18:27:25 25 4
gpt4 key购买 nike

我正在研究 Python 生成器并决定进行一个小实验。

TOTAL = 100000000
def my_sequence():
i = 0
while i < TOTAL:
yield i
i += 1

def my_list():
return range(TOTAL)

def my_xrange():
return xrange(TOTAL)

内存使用(使用psutil获取进程RSS内存)和所用时间(使用time.time())在每个方法运行几次并取平均值后如下所示:

sequence_of_values = my_sequence() # Memory usage: 6782976B  Time taken: 9.53674e-07 s

sequence_of_values2 = my_xrange() # Memory usage: 6774784B Time taken: 2.14576e-06 s

list_of_values = my_list() # Memory usage: 3266207744B Time taken: 1.80253s

我注意到使用 xrange 生成生成器的速度始终(稍微)慢于使用 yield 生成的生成器。为什么呢?

最佳答案

我要在这个答案的开头说,这种规模的时间可能很难准确测量(最好使用 timeit),而且这些优化几乎永远不会对您的实际程序的运行时间产生任何影响 ...

好了,现在免责声明就完成了......

您需要注意的第一件事是,您只是在计算生成器/xrange 对象的构造时间——您不是在计算实际迭代值所花费的时间<支持>1 。在某些情况下创建生成器可能比创建 xrange 对象更快的原因有几个...

  1. 对于生成器的情况,您只是在创建一个生成器——生成器中的代码实际上并没有运行。这相当于大约 1 个函数调用。
  2. 对于 xrange 的情况,您正在调用函数 and 然后您必须查找全局名称 xrange,全局 TOTAL,然后您需要调用该内置函数——所以在这种情况下要执行更多的事情。

至于内存——在这两种惰性方法中,使用的内存将由 python 运行时支配——而不是生成器对象的大小。内存使用受到脚本明显影响的唯一情况是构建包含 1 亿个项目的列表。

另请注意,我实际上无法在我的系统上始终如一地确认您的结果...使用 timeit,我实际上得到 my_xrange有时2 构建速度更快(约 30%)。

将以下内容添加到脚本的底部:

from timeit import timeit
print timeit('my_xrange()', setup='from __main__ import my_xrange')
print timeit('my_sequence()', setup='from __main__ import my_sequence')

我的结果是(对于 OS-X El-Capitan 上的 CPython):

0.227491140366
0.356791973114

然而,pypy 似乎有利于生成器构造(我先用 my_xrangemy_sequence 尝试过,但得到了相当一致的结果第一个运行的似乎有点不利——可能是由于 JIT 预热时间或其他原因):

0.00285911560059
0.00137305259705

1在这里,我期望 xrange 有优势——但同样,在您timeit 然后只有当时间差异很大时它才为真,并且只有在您进行计时的计算机上它才为真。
2见开头免责声明:-P

关于python - 为什么 yield 生成的生成器比 xrange 生成的生成器快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38626308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com