Project Eulerやその他のコーディングコンテストでは、実行までの最大時間が設定されていたり、自分の特定のソリューションがいかに速く実行されるかを自慢する人がいます。 pythonの場合は、__main__
にタイミングコードを追加するなど、やや不器用なアプローチもあります。
pythonプログラムの実行時間をプロファイリングする良い方法はありますか?
PythonにはcProfileというプロファイラが搭載されています。全体の実行時間だけでなく、各関数を個別に計算し、それぞれの関数が何回呼ばれたかを教えてくれるので、どこを最適化すべきかを簡単に判断することができます。
コードの中からでも、インタプリタからでも、次のように呼び出すことができます。
import cProfile
cProfile.run('foo()')
さらに便利なのは、スクリプトの実行時にcProfileを呼び出すことです。
python -m cProfile myscript.py
さらに簡単にするために、「profile.bat」という小さなバッチファイルを作りました。
python -m cProfile %1
というバッチファイルを作ったので、あとは実行するだけです。
profile euler048.py
そして、このようになります。
1007 function calls in 0.061 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.061 0.061 <string>:1(<module>)
1000 0.051 0.000 0.051 0.000 euler048.py:2(<lambda>)
1 0.005 0.005 0.061 0.061 euler048.py:2(<module>)
1 0.000 0.000 0.061 0.061 {execfile}
1 0.002 0.002 0.053 0.053 {map}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler objects}
1 0.000 0.000 0.000 0.000 {range}
1 0.003 0.003 0.003 0.003 {sum}
EDIT: PyCon 2013での良いビデオ資料へのリンクを更新しました。 Python Profiling [また、YouTubeでも公開しています](
プロファイラの使用は(デフォルトでは)メインスレッドでのみ機能し、他のスレッドを使用しても情報は得られないことを指摘しておきましょう。 これはprofiler documentationでは全く言及されていないので、ちょっとした問題になります。
スレッドのプロファイリングも行いたい場合は、ドキュメントの threading.setprofile()` function を参照してください。
また、独自の threading.Thread
サブクラスを作成することもできます。
class ProfiledThread(threading.Thread):
# Overrides threading.Thread.run()
def run(self):
profiler = cProfile.Profile()
try:
return profiler.runcall(threading.Thread.run, self)
finally:
profiler.dump_stats('myprofile-%d.profile' % (self.ident,))
を作成して、標準のクラスの代わりにその ProfiledThread
クラスを使用することもできます。 より柔軟性が増すかもしれませんが、特にあなたのクラスを使わないようなサードパーティのコードを使用している場合には、その価値があるかどうかはわかりません。