私はフィボナッチ関数を使ってmemoizedデコレータ運動をしています。 memoized関数は、結果が再び計算される代わりに辞書から結果を返すので、入力が大きくなるとはるかに高速になるはずです。メモ化デコレータが元の関数よりも遅く実行される
私はを使用して、voをオフにしてメモした関数の実行時間を測定しています。 私が得た結果は、私が期待しているものとまったく逆です。デコレータのない実行ははるかに速く実行されます。
# memorized decorator for fibonacci series
def mem_fib(f):
def wrapper(n):
wrapper.d = {} # create the attr member of THIS wrapper
if n in wrapper.d:
return wrapper.d[n]
wrapper.d[n] = f(n) # save f() return in a dict
return wrapper.d[n]
return wrapper
@mem_fib
def fibonacci(n):
assert n >= 0
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
私はPyCharmのPythonのコンソールでコマンドを実行しています。
@withデコレータ
>>> print(timeit.timeit('decorators.fibonacci(7)', setup='import decorators'))
19.6940833939
>>> print(timeit.timeit('decorators.fibonacci(10)', setup='import decorators'))
85.7157191166
デコレータ
>>> print(timeit.timeit('decorators.fibonacci(7)', setup='import decorators'))
5.10131571594
>>> print(timeit.timeit('decorators.fibonacci(10)', setup='import decorators'))
21.9784012801
のない私ははtimeit複数回走った、私はちょうどそれを合計する1つの出力を置きます。私は何が欠けていますか?
おかげ
更新:ダニエルの答えのおかげで、私は私のミスを発見しました。私はラッパーの外で辞書の作成を移動し、結果ははるかに優れていた。
>>> print(timeit.timeit('decorators.fibonacci(10)', setup='import decorators'))
0.248986574759
大きな値には疲れましたか?私の推測では、7と10の場合、メモ作成によって導入されたわずかなオーバーヘッドは実際の計算のコストよりも大きいことになります。私はfibbonacci(100)の場合、期待される結果が得られると思います。 –
それはあなたの主張の声明のためでしょうか?また、補足として、最後にパスステートメントは必要ありません。負のnをチェックしてエラーを出し、ベースケースをチェックして戻ります。両方のチェックが失敗した場合は、再帰的なケースでなければならないため、elseを使用する必要はありません。 – Mai
この小さな変更は、コードを読みやすくします。注釈のおかげです。 – Vinny