Yan*_* Yi 10 python yield python-2.7 python-3.x
我正在调查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)
Run Code Online (Sandbox Code Playgroud)
在运行每个方法几次并取平均值后,内存使用情况(使用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
Run Code Online (Sandbox Code Playgroud)
我注意到使用xrange生成一个生成器始终(略微)慢于使用yield.为什么会这样?
我将在这个答案的前言中说,这种规模的时间可能难以准确测量(可能最好使用timeit),并且这些优化几乎不会对实际程序的运行时间产生任何影响......
好的,现在免责声明已经完成......
您需要注意的第一件事是您只是计算生成器/ xrange对象的构造 - 您没有计算实际迭代值1所花费的时间.有些原因导致创建生成器在某些情况下可能比创建xrange对象更快...
xrange情况,你正在调用函数,然后你必须查找全局名称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')
Run Code Online (Sandbox Code Playgroud)
我的结果是(适用CPython于OS-X El-Capitan):
0.227491140366
0.356791973114
Run Code Online (Sandbox Code Playgroud)
然而,pypy似乎有利于发电机构造(我尝试了它的my_xrange第一个和my_sequence第一个并得到相当一致的结果虽然第一个运行似乎有点不利 - 可能是由于JIT热身时间或某事):
0.00285911560059
0.00137305259705
Run Code Online (Sandbox Code Playgroud)
1在这里,我希望 xrange有优势 - 但是,直到你再没有什么是真的timeit,只有当时间差异很大并且只在你做时间的计算机上才是真的.
2见开放免责声明:-P
| 归档时间: |
|
| 查看次数: |
184 次 |
| 最近记录: |