どのようにすることができますプロファイルをPythonスクリプト?
-
06-09-2019 - |
質問
プロジェクトオイラーおよびその他の符号化のコンテストが最大実行時間は人が自慢の速度をどのように特定の溶液を運行しています。Pythonのアプローチややkludgey、追加のタイミングコード __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のプロファイリングののの
また、YouTubeのを経由してます。
他のヒント
以前から作った pycallgraph
を生成する可視化からPythonコードです。 編集: 更新しましたの例を作3.3を用いることにより、最新のリリースします。
した後、 pip install pycallgraph
の設置 GraphViz できるコマンドラインから:
pycallgraph graphviz -- ./mypythonscript.py
または、プロの特定の部品コード:
from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput
with PyCallGraph(output=GraphvizOutput()):
code_to_profile()
これらを生む pycallgraph.png
ファイルと同様の画像。
で指摘を使用したプロファイラがなくなデフォルトのスレッド、すな情報からその他のスレッドご利用の場合です。このとき少しgotchaそのまま完全にunmentionedの プロファイラー文書.
まもりたいのプロフィールドを見ると良いでしょう、 threading.setprofile()
機能 のdocsに入ります。
きもの作成 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
クラスの代わりに標準です。あまりの柔軟性が必要な場合はこちらでは、特にご利用の場合は第三者コードな使用クラスです。
Pythonのwikiにはリソースをプロファイリングするための偉大なページです。 http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code の
Pythonのドキュメントがあるとして: http://docs.python.org/library/profile.html の
クリスロウラーズcProfileによって示されるように、の優れたツールであり、容易に画面に出力するために使用することができます:
python -m cProfile -s time mine.py <args>
またはファイルに:
python -m cProfile -o output.file mine.py <args>
PS> Ubuntuを使用している場合は、のpython-プロファイルをインストールしてください。
sudo apt-get install python-profiler
は、
次のツールを使用して、素敵な視覚化を得ることができます出力をファイルにした場合 PyCallGraph:コールグラフ・イメージを作成するためのツール
インストール:
sudo pip install pycallgraph
を実行します。
pycallgraph mine.py args
ビューます:
gimp pycallgraph.png
あなたはPNGファイルを表示したいものを使用することができ、私はGIMPを使用の
残念ながら、私は多くの場合、取得
ドット:グラフはカイロ・レンダラのビットマップの大きすぎます。
フィットする0.257079によってスケーリング私のイメージはunusably小さくしています。だから私は、一般的にSVGファイルを作成します:
pycallgraph -f svg -o pycallgraph.svg mine.py <args>
PS>(ドットプログラムを提供)graphvizのをインストールすることを確認します:
sudo pip install graphviz
オルタナティヴグラフ@maxy / @quodlibetor経由gprof2dot使用します:
sudo pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg
にMAXYさんのコメント@この回答には、私はそれは、独自の答えに値すると思うことを十分に私を助け:私はすでにcProfileを持っていました-generated .pstatsファイルは、私は再実行するpycallgraphで物事をしたくなかったので、私は<使用のhref =「http://code.google.com/p/jrfonseca/wiki/Gprof2Dot」のrel =「noreferrer」 > gprof2dot の、そしてかなりsvgsを得ます:
$ sudo apt-get install graphviz
$ git clone https://github.com/jrfonseca/gprof2dot
$ ln -s "$PWD"/gprof2dot/gprof2dot.py ~/bin
$ cd $PROJECT_DIR
$ gprof2dot.py -f pstats profile.pstats | dot -Tsvg -o callgraph.svg
とBLAM!
これは、(pycallgraphが使用するのと同じもの)のドットを使用していますので、出力は似ています。私はしかしgprof2dotが少ない情報を失うという印象を受ける。
私はこのトピックを研究する際に SnakeViz に呼ばれる便利なツールに走りました。 SnakeVizは、Webベースのプロファイリング可視化ツールです。インストールして使用することは非常に簡単です。私はそれを使用する通常の方法は%prun
とのstatファイルを生成し、SnakeVizで分析を行うことです。
以下に示すように使用される主すなわち技術は関数の階層を呼び出した、のサンバーストチャートのでは円弧とその角度幅で符号化された時間情報の層として配置されている。
最善のことは、あなたがチャートと対話することができます。例えば、一つにズームすることが円弧上でクリックすることができ、アークとその子孫は、より多くの詳細を表示するには、新しいサンバーストとして拡大されます。
ると思い cProfile
はプロファイリングが kcachegrind
で可視化。の pyprof2calltree
間取り扱うファイルに変換します。
python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltree
インストールに必要なツール(Ubuntuの場合、少なくとも):
apt-get install kcachegrind
pip install pyprof2calltree
その結果、
また、言及する価値 RunSnakeRun のGUI cProfileダンプビューアです。それによってプログラムの関連部分にズームイン、あなたが並べ替えを選択することができます。画像内の長方形の大きさは、撮影した時間に比例しています。四角形の上にあなたのマウスなら、それは表にし、どこでも地図上にそのコールを強調表示します。あなたは長方形をダブルクリックするとその部分が拡大表示されます。これは、その部分を呼び出して、どのようなその部分呼び出し方を紹介します。
の記述情報は非常に有用です。それはあなたが組み込みのライブラリ呼び出しを扱っている際に参考にすることができ、そのビットのコードを示します。それはあなたがどのようなファイルや何行のコードを見つけることが伝えています。
また、OPは、「プロファイリング」と述べていることを指すようにしたいが、彼が「タイミング」を意味表示されます。プロファイリング時に実行速度が低下します心のプログラムに保管してください。
最も簡単な や 迅速 この場に追い込まれています。
1. pip install snakeviz
2. python -m cProfile -o temp.dat <PROGRAM>.py
3. snakeviz temp.dat
を描くためには、グ、ブラウザです。最大の作品が問題なの機能です。非常に簡単です。
素敵なプロファイリングモジュールは、(スクリプトkernprof.pyを使用して呼ばれる)line_profilerです。それはここのをダウンロードすることができます。
私の理解では、cProfileが唯一の各関数で費やされた合計時間についての情報を与えることです。コードのため、個々の行がタイムアウトされていません。多くの場合、1つの行は、多くの時間を取ることができますので、これは科学的なコンピューティングの問題です。また、私が覚えているとして、cProfileは、私が言うのnumpy.dotに費やした時間をキャッチしませんでした。
pprofile
と記載されている line_profiler
(既にここに提示)は触発 pprofile
に、
ライン粒度、スレッド対応決定論と統計純粋-pythonの プロファイラ
これは、line_profiler
としてライン粒状度を提供する純粋のPythonで、スタンドアロンのコマンドまたはモジュールとして使用することができ、さらに容易[k|q]cachegrind
で分析することができるcallgrind形式のファイルを生成することができます。
vprof
また、 vprof の、と説明したPythonパッケージがあります:
[...]このような時間とメモリ使用量を実行するなどの様々なPythonプログラム特性のためにリッチでインタラクティブな視覚化を提供する。
私は最近、Pythonランタイムとインポートプロファイルを可視化するためのマグロを作成しました。これはここに役立つかもしれない。
タグでのインストール
pip3 install tuna
実行時プロファイルを作成します。
python -mcProfile -o program.prof yourfile.py
またはインポート・プロファイル(パイソン3.7+必要)
python -X importprofile yourfile.py 2> import.log
それからちょうどファイルにマグロを実行します。
tuna program.prof
があり偉大な答えの多くはだが、彼らは、プロファイリングのために、コマンドラインまたはいくつかの外部プログラムを使用し、および/または結果をソートするのいずれか。
私は本当に私は、コマンドラインに触れるか、何もインストールすることなく、私のIDE(EclipseをPyDevは)に使用できるいくつかの方法を逃しました。だから、ここにある。
コマンドラインなしのプロファイリング
def count():
from math import sqrt
for x in range(10**5):
sqrt(x)
if __name__ == '__main__':
import cProfile, pstats
cProfile.run("count()", "{}.profile".format(__file__))
s = pstats.Stats("{}.profile".format(__file__))
s.strip_dirs()
s.sort_stats("time").print_stats(10)
ドキュメントのか、詳細は他の回答を参照してください。
期待どおりに動作しない、マルチスレッド・コードについてジョー・ショーの答えに続いて、私はcProfileでruncall
方法は、単に、プロファイル関数呼び出しの周りself.enable()
とself.disable()
呼び出しを行っていることを考え出したので、あなたは、単に自分自身としているものは何でもコードすることを行うことができますあなたは、既存のコードで最小の干渉との間で、欲しいます。
Virtaalのソースでは非常に便利なクラスがありますと(でも、特定のメソッド/機能のための)プロファイリングを行うことができますデコレータは非常に簡単。出力は、KCacheGrindで非常に快適に閲覧することができます。
cProfileは、迅速なプロファイリングのための素晴らしいですが、それはエラーで私のために終了されたほとんどの時間。機能runctxは、それが誰かのために有用であることを願って、正しく環境変数を初期化することによってこの問題を解決します:
import cProfile
cProfile.runctx('foo()', None, locals())
私の方法は、yappiを使用することです( https://code.google.com/p/yappi/する) 。それは、例えば、起動、停止および印刷プロファイリング情報するメソッドを登録(だけでも、デバッグのため)RPCサーバーと組み合わせて、特に便利ですこのように:
@staticmethod
def startProfiler():
yappi.start()
@staticmethod
def stopProfiler():
yappi.stop()
@staticmethod
def printProfiler():
stats = yappi.get_stats(yappi.SORTTYPE_TTOT, yappi.SORTORDER_DESC, 20)
statPrint = '\n'
namesArr = [len(str(stat[0])) for stat in stats.func_stats]
log.debug("namesArr %s", str(namesArr))
maxNameLen = max(namesArr)
log.debug("maxNameLen: %s", maxNameLen)
for stat in stats.func_stats:
nameAppendSpaces = [' ' for i in range(maxNameLen - len(stat[0]))]
log.debug('nameAppendSpaces: %s', nameAppendSpaces)
blankSpace = ''
for space in nameAppendSpaces:
blankSpace += space
log.debug("adding spaces: %s", len(nameAppendSpaces))
statPrint = statPrint + str(stat[0]) + blankSpace + " " + str(stat[1]).ljust(8) + "\t" + str(
round(stat[2], 2)).ljust(8 - len(str(stat[2]))) + "\t" + str(round(stat[3], 2)) + "\n"
log.log(1000, "\nname" + ''.ljust(maxNameLen - 4) + " ncall \tttot \ttsub")
log.log(1000, statPrint)
次に、あなたのプログラムの仕事はあなたがstartProfiler
のRPCメソッドを呼び出すことにより、任意の時点でプロファイラを起動してprintProfiler
を呼び出すことにより、ログファイルにプロファイル情報をダンプ(または、呼び出し元に戻すために、RPCメソッドを変更)し、このような出力を得ることができたときに:
2014-02-19 16:32:24,128-|SVR-MAIN |-(Thread-3 )-Level 1000:
name ncall ttot tsub
2014-02-19 16:32:24,128-|SVR-MAIN |-(Thread-3 )-Level 1000:
C:\Python27\lib\sched.py.run:80 22 0.11 0.05
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\xmlRpc.py.iterFnc:293 22 0.11 0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\serverMain.py.makeIteration:515 22 0.11 0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\PicklingXMLRPC.py._dispatch:66 1 0.0 0.0
C:\Python27\lib\BaseHTTPServer.py.date_time_string:464 1 0.0 0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py._get_raw_meminfo:243 4 0.0 0.0
C:\Python27\lib\SimpleXMLRPCServer.py.decode_request_content:537 1 0.0 0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py.get_system_cpu_times:148 4 0.0 0.0
<string>.__new__:8 220 0.0 0.0
C:\Python27\lib\socket.py.close:276 4 0.0 0.0
C:\Python27\lib\threading.py.__init__:558 1 0.0 0.0
<string>.__new__:8 4 0.0 0.0
C:\Python27\lib\threading.py.notify:372 1 0.0 0.0
C:\Python27\lib\rfc822.py.getheader:285 4 0.0 0.0
C:\Python27\lib\BaseHTTPServer.py.handle_one_request:301 1 0.0 0.0
C:\Python27\lib\xmlrpclib.py.end:816 3 0.0 0.0
C:\Python27\lib\SimpleXMLRPCServer.py.do_POST:467 1 0.0 0.0
C:\Python27\lib\SimpleXMLRPCServer.py.is_rpc_path_valid:460 1 0.0 0.0
C:\Python27\lib\SocketServer.py.close_request:475 1 0.0 0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\__init__.py.cpu_times:1066 4 0.0 0.0
これは、短いスクリプトのために非常に便利ですが、特にprintProfiler
方法は、プロファイルと比較することで、例えば時間をかけて複数回呼び出すことができ、特定のサーバタイプのプロセスを最適化するのに役立ちますないかもしれません別のプログラムの使用シナリオ。
は、これまでPythonスクリプトが何をしているか地獄いることを知りたいですか?入力します シェルを点検してください。点検シェルは、あなたが/グローバルと実行を変更し印刷することができます 実行中のスクリプトを中断することなく機能します。今で オートコンプリートと(のみLinuxの場合)コマンド履歴ます。
シェルは、PDB形式のデバッガではありません点検します。
https://github.com/amoffat/Inspect-Shellする
あなたは(と自分の腕時計を)使用することができます。
https://stackoverflow.com/a/582337/1070617 に、
へ追加します私はあなたがcProfileを使用して、簡単にその出力を表示することができ、このモジュールを書きました。もっとここに: https://github.com/ymichael/cprofilevする
$ python -m cprofilev /your/python/program
# Go to http://localhost:4000 to view collected statistics.
も参照してください: http://ymichael.com/収集された統計の意味を理解する方法について2014/03/08 /プロファイリング-のpython-と-cprofile.htmlするます。
新しいツールを扱うプロファイリングPythonはPyVmMonitor: http://www.pyvmmonitor.com/
この特徴ある独特など
- 添付プロファイラーにランニング(CPython)プログラム
- マプロファイリングとYappi統合
- プロフィールマシン
- 複数の工程をサポート(マルチプロセベ...)
- ライブサンプリング/CPUビュー(時間範囲選択)
- 決定論的プロファイリングを通じてcProfile/プロフィール統合
- 分析し、既存のPStats結果
- 開DOTファイル
- Programatic APIアクセス
- グループのサンプルによる方法やライン
- PyDev統合
- PyCharm統合
注意:この商ですが、無料のためのオープンソースです。
でに頼ることになるでしょういれているということもあり、プロファイリング.簡単な時間 メトリックすることができ(bashの場合).
time python python_prog.py
でも'/usr/bin/時間を出力することが可能で詳細なメトリクスを用いた--verbose'フラグ。
チェック時にメトリクスによる各機能の解がどを駆使し、機能を利用できる組み込みcProfile。
いより詳細なメトリクスのような性能、時間だけではない)。できる気メモリ、スレッドなど。
プロファイリングオプション:
1. line_profiler 別のプロファイラーに用いられている見出しタイミングメトリクス線による。
2. memory_profiler ツールのプロフィールのメモリ使用量
3. heapyからプロジェクトGuppy) Profileどのようにヒープを使用します。
これらは一般的なものにしていっています。だいたい場合はキャンセルとなりました。を読んでみてはどうでしこ 書籍 では良い本を出した性能です。移動でき込先端の話題をウェやJIT(Just in time)ディストリビュータ。
statprof
すると呼ばれる統計的プロファイラもあります。これは、サンプリングプロファイラですので、それはあなたのコードに最小限のオーバーヘッドを追加し、ラインベース(だけでなく、機能ベースの)タイミングを提供します。それはゲームのようなソフトリアルタイム・アプリケーションに適しだが、cProfile未満の精度を持っていることがあります。
pip install git+git://github.com/bos/statprof.py@1a33eba91899afe17a8b752c6dfdec6f05dd0c01
あなたはこのようにそれを実行することができます:
import statprof
with statprof.profile():
my_questionable_function()
も参照してください。 https://stackoverflow.com/a/10333592/320036 の
私は、サーバー上のルートじゃないときは、私が使用 lsprofcalltree.py と、このように私のプログラムを実行します:
python lsprofcalltree.py -o callgrind.1 test.py
それから私は、 qcachegrindする
gprof2dot_magic
マジック機能 gprof2dot
プロフィール他のPythonで書としてのドットグラフJupyterLabはJupyterノートに記録していました。
GitHubのレポ-レート: https://github.com/mattijn/gprof2dot_magic
設置
になるPythonパッケージ gprof2dot_magic
.
pip install gprof2dot_magic
その依存関係 gprof2dot
や graphviz
まとしてインストールすることも
用途
ためのマジック機能、負荷の gprof2dot_magic
モジュール
%load_ext gprof2dot_magic
その概要当行書としてのドットグラフなど:
%gprof2dot print('hello world')
端子のみ(最も単純な)ソリューションこれらすべての空想のUIのインストールするか、実行に失敗した場合:
右の実行後に呼び出しのツリーを収集し、表示すること、完全にcProfile
を無視しpyinstrument
と交換します。
インストールします:
$ pip install pyinstrument
プロファイルと表示結果:
$ python -m pyinstrument ./prog.py
python2と3で動作します。