Python では、純粋な再帰関数を再帰ジェネレーター (単純なジェネレーターではない) に変更すると、パフォーマンスが低下するようです。
たとえば、リストのすべての組み合わせを見つける 2 つの関数のパフォーマンス比較を次に示します。
from datetime import datetime as dt
def rec_subsets(ms, i=0, s=[]):
if i == len(ms):
# do something with s
return
rec_subsets(ms, i+1, s)
rec_subsets(ms, i+1, s + [ms[i]])
def gen_subsets(ms, i=0, s=[]):
if i == len(ms):
yield s
return
for a in gen_subsets(ms, i+1, s): yield a
for a in gen_subsets(ms, i+1, s + [ms[i]]): yield a
t1 = dt.now()
rec_subsets(range(20))
t2 = dt.now()
print t2 - t1
t1 = dt.now()
for _ in gen_subsets(range(20)): pass
t2 = dt.now()
print t2 - t1
次の出力で:
0:00:01.027000 # rec_subsets
0:00:02.860000 # gen_subsets
当然のことながら、gen_subsetsはrec_subsetsとほぼ同じ速度であると予想されますが、そうではなく、はるかに低速です。
これは正常ですか、それとも何か不足していますか?