2011-09-23 10 views
60

私は、この使用はtimeitに苦しんだし、誰もが任意のヒント関数に変数を渡すときにpython 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 

私が独自に機能を実行すると、それが正常に動作します。そのモジュールをそれをまとめたときにラップすると、エラーが出ます(私は二重引用符を使用して試しています。

どのような提案もすばらしいでしょう。

ありがとうございます!

答えて

95

それが呼び出し可能行います

if __name__=='__main__': 
    from timeit import Timer 
    t = Timer(lambda: superMegaIntenseFunction(10)) 
    print t.timeit(number=1) 

+0

これはうまくいきました!本当にありがとう。私はラムダが何をしているのか把握する必要があります。ありがとうPablo – Lostsoul

+5

これはドキュメント内のどこかにある場合 – endolith

+13

ああしかし、ラムダはいくつかのオーバーヘッドを追加するので、小さなものをテストするのには理想的ではありません。 'timeit 5 * 5'は33nsであり、' timeit(lambda:5 * 5)() 'は233nsです。 – endolith

16

文字列を渡す必要があります。すなわち

t = Timer('superMegaIntenseFunction(10)','from __main__ import superMegaIntenseFunction') 
+0

感謝を!私は引用符で囲んだので、それは文字列私はこのエラーが表示されます:NameError:グローバル名 'superMegaIntenseFunction'は定義されていません。私は何を試すことができると思いますか? – Lostsoul

+0

セットアップ引数を含む答えが訂正されました。 (http://docs.python。org/library/timeit.html#timeit.Timer) –

21

Timer(superMegaIntenseFunction(10)) "はTimerに結果を渡し、その後、superMegaIntenseFunction(10)を呼ぶ" という意味に動作するはずです。それは明らかにあなたが望むものではありません。 Timerは、呼び出し可能(呼び出し音と同じように、関数など)または文字列(Pythonコードとして文字列の内容を解釈できるように)のいずれかを想定しています。 Timerは、callable-thingを繰り返し呼び出して、どれくらいの時間がかかっているかを確認することで動作します。

Timer(superMegaIntenseFunction)は、superMegaIntenseFunctionが呼び出し可能であるため、型チェックに合格します。ただし、Timerは、どの値をsuperMegaIntenseFunctionに渡すかわかりません。

この単純な方法はもちろん、コードに文字列を使用することです。文字列は新鮮な文脈で "コードとして解釈される"ため、コードに 'setup'引数を渡す必要があります。同じglobalsへのアクセス権がないため、別のビットを実行して定義は利用可能です - @ oxtopusの答えをご覧ください。

lambda(@パブロの回答のように)10superMegaIntenseFunctionへの呼び出しにバインドすることができます。私たちがやっていることは、引数を取らない別の関数を作成し、superMegaIntenseFunction10と呼ぶことです。それは、新しい関数が名前を取得しないことを除いて(それが必要でないため)defを使って別の関数を作成した場合と同じです。

1

将来の訪問者のための注意。あなたはそれがpdbデバッガで動作させる必要がある、とsuperMegaIntenseFunctionはグローバルスコープにない場合、あなたはそれがglobalsに追加することで動作させることができます。回答oxtopusため

globals()['superMegaIntenseFunction'] = superMegaIntenseFunction 
timeit.timeit(lambda: superMegaIntenseFunction(x)) 

Note that the timing overhead is a little larger in this case because of the extra function calls. [source]

関連する問題