我在摆弄 Python 的生成器和可迭代类,只是为了好玩。基本上,我想测试一些我从来都不太确定的东西:Python 中的类有一些显着的开销,如果可以的话,最好依赖实现的方法yield
而不是实现迭代器协议的类。
我在 Google 中找不到关于这个主题的令人满意的解释,所以我决定使用这两个简单的脚本自己测试它们:func_iter.py
和class_iter.py
这是func_iter.py
:
#!/usr/bin/env python
import time
x = 0
def create_generator(num):
mylist = range(num)
for i in mylist:
yield i
t = time.time()
gen = create_generator(100000)
for i in gen:
x = x + i
print "%.3f" % (time.time() - t)
这是class_iter.py
:
#!/usr/bin/env python
import time
x = 0
class Generator(object):
def __init__(self, num):
self.start = 0
self.end = num
def __iter__(self):
return self
def next(self):
if self.start == self.end:
raise StopIteration
else:
self.start = self.start + 1
return self.start
t = time.time()
gen = Generator(100000)
for i in gen:
x = x + i
print "%.3f" % (time.time() - t)
然后我在 bash 中使用它运行了它们每个 10 次(class_iter.py
例如):
for i in {1..10}; do ./class_iter.py; done
以下是他们每个人的平均运行时间:
class_iter.py: 0.0864
func_iter.py: 0.0307
现在,我的问题是:
- 我的方法正确吗?我的比较公平吗?
- 如果是这样,为什么会有很大的不同?为什么
class_iter.py
要花将近三倍的时间func_iter.py
才能运行? - 如果没有,我该如何改进我的方法或提出更好的比较?
编辑:正如 Dacav 建议的那样,我也尝试func_iter.py
使用xrange
而不是range
. 这将其平均运行时间减少到 0.0263 秒。