私はtimeitを使用してこれに苦労しており、誰かがヒントを持っているかどうか疑問に思っていました
基本的に、速度をテストして作成した関数(値を渡す関数)があります。
if __name__=='__main__':
from timeit import Timer
t = Timer(superMegaIntenseFunction(10))
print t.timeit(number=1)
しかし、実行すると、timeitモジュールからのような奇妙なエラーが発生します。
ValueError: stmt is neither a string nor callable
関数を単独で実行すると、正常に機能します。そのモジュールにラップすると、エラーが発生します(二重引用符を使用して、.. sameoutputなしで試しました)。
どんな提案でも素晴らしいでしょう!
ありがとう!
それを呼び出し可能にします:
if __name__=='__main__':
from timeit import Timer
t = Timer(lambda: superMegaIntenseFunction(10))
print(t.timeit(number=1))
動作するはずです
Timer(superMegaIntenseFunction(10))
は、「superMegaIntenseFunction(10)
を呼び出し、その結果をTimer
に渡す」ことを意味します。それは明らかにあなたが望むものではありません。 Timer
は、呼び出し可能なもの(聞こえるとおり:関数など、呼び出すことができるもの)または文字列(文字列の内容をPython code)。Timer
はcallable-thingを繰り返し呼び出して、どれだけ時間がかかっているかを確認することで機能します。
superMegaIntenseFunction
は呼び出し可能なため、Timer(superMegaIntenseFunction)
は型チェックに合格します。ただし、Timer
はsuperMegaIntenseFunction
に渡す値を知りません。
もちろん、これを回避する簡単な方法は、コードで文字列を使用することです。文字列は新しいコンテキストで「コードとして解釈される」ため、「setup」引数をコードに渡す必要があります。同じglobals
にアクセスできないため、別のビットを実行する必要があります定義を利用可能にするコードの詳細-@oxtopusの回答を参照してください。
lambda
(@Pabloの答えのように)を使用すると、パラメーター10
をsuperMegaIntenseFunction
の呼び出しにバインドできます。私たちがしていることは、引数を取らず、10
でsuperMegaIntenseFunction
を呼び出す別の関数を作成することだけです。 def
を使用してそのような別の関数を作成した場合と同じです。ただし、新しい関数は名前を取得しません(名前が必要ないため)。
文字列を渡す必要があります。つまり.
t = Timer('superMegaIntenseFunction(10)','from __main__ import superMegaIntenseFunction')
将来の訪問者へのメモ。 pdb
デバッガーで動作させる必要があり、superMegaIntenseFunction
がグローバルスコープにない場合は、globals
に追加して動作させることができます。
globals()['superMegaIntenseFunction'] = superMegaIntenseFunction
timeit.timeit(lambda: superMegaIntenseFunction(x))
この場合、余分な関数呼び出しのために、タイミングのオーバーヘッドが少し大きくなることに注意してください。 [ソース]
これを行う1つの方法は、パーシャルを使用して、関数 'superMegaIntenseFunction'を呼び出し可能として(つまり()なしで)タイマーで、またはtimeit.timeitの内部で直接使用することです。 partialを使用すると、タイマーによって呼び出されるときに関数に引数が渡されます。
from functools import partial
from timeit import timeit
print(timeit(partial(superMegaIntenseFunction, 10), number=1))