私は楽しみのために、Python のジェネレーターと反復可能なクラスをいじっていました。基本的に、あまり確信が持てないことをテストしたかったのです。つまり、Python のクラスにはかなりのオーバーヘッドがありyield
、可能であれば、反復子プロトコルを実装するクラスではなく、実装するメソッドに依存する方がよいということです。
func_iter.py
Google でこのトピックに関する満足のいく説明を見つけることができなかったので、次の 2 つの簡単なスクリプトを使用して自分でテストすることにしました。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
実行に約 3 倍の時間がかかったのはなぜfunc_iter.py
ですか? - そうでない場合、どのように方法を改善したり、より良い比較を考え出すことができますか?
編集: Dacav が示唆したように、代わりに をfunc_iter.py
使用して実行してみました。これにより、平均実行時間が 0.0263 秒に短縮されます。xrange
range