我只是在玩弄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秒。
我只是在玩弄Python的生成器和可迭代的类。基本上,我想测试一下我从未确定过的东西:Python中的类具有一些...
类版本花费大量时间来访问其自己的变量。每个self.whatever
都需要一个周期。如果将__iter__
定义为生成器,并最小化实例变量的使用,则类和函数版本之间的差异可以忽略不计:
如果您使用的是python,则很有可能您并非以软件性能为目标,而是更在意开发中的敏捷和敏捷。
您似乎是完全正确的,您的比较是公正的。仅比较开销时,支持迭代器协议的类将比生成器函数慢。