多くの場合、プロジェクトオイラーやその他のコーディングコンテストの実行時間は最大であるか、特定のソリューションの実行速度が自慢です。Pythonでは、時々アプローチがややこしい-つまり、タイミングコードをに追加する__main__
。
Pythonプログラムの実行にかかる時間をプロファイルする良い方法は何ですか?
多くの場合、プロジェクトオイラーやその他のコーディングコンテストの実行時間は最大であるか、特定のソリューションの実行速度が自慢です。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}
編集:PyCon 2013の優れた動画リソースへのリンクを更新し、「Pythonプロファイリング
もYouTube経由」というタイトルを付け
ました。
python -m cProfile -o <out.profile> <script>
)を視覚化するために、RunSnakeRunrunsnake <out.profile>
が非常に貴重な方法で呼び出されます。
cprofile
でも推奨されprofile
ます。
少し前に私は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
以下の画像のようなファイルが生成されます。
Traceback (most recent call last): /pycallgraph.py", line 90, in generate output.done() File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 94, in done source = self.generate() File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 143, in generate indent_join.join(self.generate_attributes()), File "/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py", line 169, in generate_attributes section, self.attrs_from_dict(attrs), ValueError: zero length field name in format
sudo apt-get install graphviz
です。
プロファイラーの使用はメインスレッドでのみ(デフォルトで)機能し、他のスレッドを使用しても情報を取得できないことに注意してください。プロファイラーのドキュメントにはまったく記載されていないため、これはちょっとした問題になる可能性があります。
スレッドもプロファイリングしたい場合は、ドキュメント内のthreading.setprofile()
関数を確認する必要があります。
また、独自の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
標準のクラスの代わりにそのクラスを使用します。柔軟性が高まるかもしれませんが、特にクラスを使用しないサードパーティのコードを使用している場合は、その価値があるかどうかはわかりません。
target
ここでは、threading.Thread.run()
呼び出しが実行するスレッドの関数のプロファイルを作成します。しかし、答えで述べたように、スレッドをサブクラス化しても、サードパーティのコードでは使用せず、代わりにを使用する価値はありませんthreading.setprofile()
。
Python Wikiは、プロファイリングリソースに最適なページです。http: //wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code
Pythonのドキュメントと同様に:http : //docs.python.org/library/profile.html
Chris Lawlorが示すように、cProfileは優れたツールであり、画面への印刷に簡単に使用できます。
python -m cProfile -s time mine.py <args>
またはファイルする:
python -m cProfile -o output.file mine.py <args>
PS> Ubuntuを使用している場合は、python-profileをインストールしてください
apt-get install python-profiler
ファイルに出力すると、次のツールを使用して素晴らしい視覚化を得ることができます
PyCallGraph:コールグラフイメージを作成するツール
インストール:
pip install pycallgraph
実行:
pycallgraph mine.py args
見る:
gimp pycallgraph.png
あなたはPNGファイルを表示したいものを使用することができ、私はGIMPを使用
残念ながら、私は頻繁に取得します
ドット:グラフはcairo-rendererビットマップには大きすぎます。フィットするように0.257079でスケーリング
これにより、画像が小さくなりすぎます。だから私は一般的にsvgファイルを作成します:
pycallgraph -f svg -o pycallgraph.svg mine.py <args>
PS>(ドットプログラムを提供する)graphvizをインストールしてください:
pip install graphviz
@maxy / @quodlibetorを介したgprof2dotを使用した代替グラフ作成:
pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg
上のMAXYさんのコメント@ この答えは十分に私を助け、私はそれは、独自の答えに値すると思うこと:私はすでにcProfile-生成.pstatsファイルを持っていたし、私が使用して私は、pycallgraphで再実行して、物事にはしたくなかった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が失う情報が少ないという印象を受けます。
pwd
/gprof2dot/gprof2dot.py $ HOME / bin(または、ほとんどのシェルでln -s $ PWD / gprof2dot / gprof2dot.py〜/ binを使用します-最初のフォーマットとしてアクサングラーブがフォーマットとして使用されますバージョン)。
ln
の引数次の間違ったほぼすべての時間を。
このトピックを調べていると、SnakeVizという便利なツールに出くわしました。SnakeVizは、Webベースのプロファイリング視覚化ツールです。インストールと使用は非常に簡単です。私がそれを使用する通常の方法は%prun
、Stat ファイルを生成してSnakeVizで分析を行うことです。
使用される主なviz手法は、以下に示すサンバーストチャートです。この関数では、関数呼び出しの階層が、円弧のレイヤーと角度幅でエンコードされた時間情報として配置されています。
一番良いのは、チャートを操作できることです。たとえば、ズームインするには、アークをクリックすると、アークとその子孫が新しいサンバーストとして拡大され、詳細が表示されます。
最も簡単かつ最速のすべての時間が起こっている場所を見つける方法。
1. pip install snakeviz
2. python -m cProfile -o temp.dat <PROGRAM>.py
3. snakeviz temp.dat
ブラウザで円グラフを描画します。最大のピースは問題の関数です。とても簡単です。
これ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
結果:
brew install qcachegrind
それぞれkcachegrind
をインストールし、qcachegrind
実質的です。
export QT_X11_NO_MITSHM=1
また言及する価値があるのは、GUI cProfileダンプビューアRunSnakeRunです。並べ替えて選択できるため、プログラムの関連部分を拡大できます。画像内の長方形のサイズは、かかる時間に比例します。長方形の上にマウスを置くと、その呼び出しがテーブル内とマップ上のすべての場所で強調表示されます。長方形をダブルクリックすると、その部分が拡大されます。誰がその部分を呼び出し、その部分が何を呼び出すかを示します。
説明的な情報は非常に役立ちます。組み込みのライブラリ呼び出しを処理するときに役立つ、そのビットのコードが表示されます。これは、コードを見つけるためのファイルと行を示します。
OPが「プロファイリング」と言ったことを指摘したいが、彼は「タイミング」を意味していたようだ。プロファイルを作成すると、プログラムの実行速度が遅くなることに注意してください。
line_profiler
(すでにここに提示されています)また pprofile
、次のように説明されています:
線の細分性、スレッド対応の確定的および統計的な純粋なPythonプロファイラー
line_profiler
は純粋なPythonであり、スタンドアロンのコマンドまたはモジュールとして使用でき、さらにで簡単に分析できるcallgrind形式のファイルを生成することもできるので、細分性を提供し[k|q]cachegrind
ます。
次のように説明されるPythonパッケージであるvprofもあります。
[...]実行時間やメモリ使用量などのさまざまなPythonプログラムの特性に対して、リッチでインタラクティブな視覚化を提供します。
すばらしい答えはたくさんありますが、結果のプロファイリングや並べ替えにコマンドラインまたは外部プログラムを使用しています。
コマンドラインに触れたり、何かをインストールしたりせずに、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)
詳細については、ドキュメントまたはその他の回答を参照してください。
マルチスレッドコードが期待どおりに機能しないというジョーショーの回答に続きruncall
、cProfile のメソッドは単に実行され、プロファイルされた関数呼び出しself.enable()
をself.disable()
呼び出しているだけであると考えました。既存のコードへの干渉を最小限に抑えます。
cprofile.py
のソースコードをざっと見ると、まさにそれが何をするのかruncall()
がわかります。より具体的には、を使用してProfileインスタンスを作成した後prof = cprofile.Profile()
、すぐにを呼び出しprof.disable()
、プロファイルを作成するコードのセクションを追加prof.enable()
してprof.disable()
呼び出します。
Virtaalのソースには、(特定のメソッド/関数の場合でも)プロファイリングを非常に簡単にすることができる非常に便利なクラスとデコレータがあります。その後、出力はKCacheGrindで非常に快適に表示できます。
累積プロファイラーを作成する場合は、関数を数回続けて実行し、結果の合計を監視します。
このcumulative_profiler
デコレータを使用できます:
それはpython> = 3.6固有ですがnonlocal
、古いバージョンで動作するように削除できます。
import cProfile, pstats
class _ProfileFunc:
def __init__(self, func, sort_stats_by):
self.func = func
self.profile_runs = []
self.sort_stats_by = sort_stats_by
def __call__(self, *args, **kwargs):
pr = cProfile.Profile()
pr.enable() # this is the profiling section
retval = self.func(*args, **kwargs)
pr.disable()
self.profile_runs.append(pr)
ps = pstats.Stats(*self.profile_runs).sort_stats(self.sort_stats_by)
return retval, ps
def cumulative_profiler(amount_of_times, sort_stats_by='time'):
def real_decorator(function):
def wrapper(*args, **kwargs):
nonlocal function, amount_of_times, sort_stats_by # for python 2.x remove this row
profiled_func = _ProfileFunc(function, sort_stats_by)
for i in range(amount_of_times):
retval, ps = profiled_func(*args, **kwargs)
ps.print_stats()
return retval # returns the results of the function
return wrapper
if callable(amount_of_times): # incase you don't want to specify the amount of times
func = amount_of_times # amount_of_times is the function in here
amount_of_times = 5 # the default amount
return real_decorator(func)
return real_decorator
例
関数のプロファイリング baz
import time
@cumulative_profiler
def baz():
time.sleep(1)
time.sleep(2)
return 1
baz()
baz
5回実行してこれを印刷しました:
20 function calls in 15.003 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
10 15.003 1.500 15.003 1.500 {built-in method time.sleep}
5 0.000 0.000 15.003 3.001 <ipython-input-9-c89afe010372>:3(baz)
5 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
回数の指定
@cumulative_profiler(3)
def baz():
...
私の方法は、yappi(https://github.com/sumerc/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
さまざまなプログラムの使用シナリオなどのプロファイルを作成して比較するために時間をかけて複数回呼び出すことができるメソッドであれば、サーバータイプのプロセスを最適化するのに役立ちます。
新しいバージョンのyappiでは、次のコードが機能します。
@staticmethod
def printProfile():
yappi.get_func_stats().print_all()
def printProfiler(): if not yappi_available: return stats = yappi.get_func_stats() stats.print_all(columns={0:("name",90), 1:("ncall", 5), 2:("tsub", 8), 3:("ttot", 8), 4:("tavg",8)})
。 )
Pythonでプロファイリングを処理する新しいツールはPyVmMonitorです:http ://www.pyvmmonitor.com/
それは次のようないくつかのユニークな機能を備えています
注:商用ですが、オープンソースの場合は無料です。
gprof2dot_magic
gprof2dot
PythonステートメントをJupyterLabまたはJupyter NotebookのDOTグラフとしてプロファイルするためのマジック関数。
GitHubリポジトリ:https : //github.com/mattijn/gprof2dot_magic
インストール
Pythonパッケージがあることを確認してくださいgprof2dot_magic
。
pip install gprof2dot_magic
その依存関係gprof2dot
とgraphviz
同様にインストールされます
使用法
マジック機能を有効にするには、まずgprof2dot_magic
モジュールをロードします
%load_ext gprof2dot_magic
次に、任意の行ステートメントをDOTグラフとしてプロファイルします。
%gprof2dot print('hello world')
Pythonスクリプトが何をしているのか知りたいですか?検査シェルに入ります。Inspect Shellを使用すると、実行中のスクリプトを中断することなく、グローバルを印刷/変更して関数を実行できます。オートコンプリートとコマンド履歴が追加されました(Linuxのみ)。
Inspect Shellは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/profiling-python-with-cprofile.htmlも参照してください。
プロファイリングで確認したい内容によって異なります。単純な時間メトリックは(bash)で指定できます。
time python python_prog.py
「/ usr / bin / time」でも、「-verbose」フラグを使用して詳細なメトリックを出力できます。
各関数によって与えられた時間メトリックをチェックし、関数に費やされた時間をよりよく理解するには、Pythonで組み込みのcProfileを使用できます。
パフォーマンスのようなより詳細なメトリックに入ると、時間だけがメトリックではありません。メモリ、スレッドなどについて心配することができ
ます。プロファイリングオプション:
1. line_profilerは、行ごとにタイミングメトリックを見つけるために一般的に使用される別のプロファイラーです。
2. memory_profilerは、メモリ使用量をプロファイルするツールです。
3. heapy(プロジェクトGuppyから)ヒープ内のオブジェクトがどのように使用されるかをプロファイルします。
これらは、私がよく使用する一般的なものです。しかし、さらに詳しく知りたい場合 は、この本を読んでみてください。これは、パフォーマンスを念頭に置いて始めることについてはかなり良い本です。CythonおよびJIT(ジャストインタイム)コンパイル済みpythonの使用に関する高度なトピックに進むことができます。
austinのような統計プロファイラーを使用すると、インストルメンテーションは不要になります。つまり、Pythonアプリケーションからプロファイリングデータを簡単に取得できます。
austin python3 my_script.py
生の出力はあまり役に立ちませんが、それをflamegraph.pl にパイプして、時間(マイクロ秒単位で測定)が費やされている場所の内訳を示すデータのフレームグラフ表現を取得できます。
austin python3 my_script.py | flamegraph.pl > my_script_profile.svg
IPythonノートブックでプロファイルの統計をすばやく取得するため。line_profilerとmemory_profilerをノートブックに直接埋め込むことができます。
別の便利なパッケージはPymplerです。これは、クラス、オブジェクト、関数、メモリリークなどを追跡できる強力なプロファイリングパッケージです。以下の例では、ドキュメントが添付されています。
!pip install line_profiler
!pip install memory_profiler
!pip install pympler
%load_ext line_profiler
%load_ext memory_profiler
%time print('Outputs CPU time,Wall Clock time')
#CPU times: user 2 µs, sys: 0 ns, total: 2 µs Wall time: 5.96 µs
与える:
%timeit -r 7 -n 1000 print('Outputs execution time of the snippet')
#1000 loops, best of 7: 7.46 ns per loop
%prun -s cumulative 'Code to profile'
与える:
%memit 'Code to profile'
#peak memory: 199.45 MiB, increment: 0.00 MiB
与える:
#Example function
def fun():
for i in range(10):
print(i)
#Usage: %lprun <name_of_the_function> function
%lprun -f fun fun()
与える:
sys.getsizeof('code to profile')
# 64 bytes
オブジェクトのサイズをバイト単位で返します。
from pympler import asizeof
obj = [1,2,("hey","ha"),3]
print(asizeof.asizeof(obj,stats=4))
pympler.asizeofを使用して、特定のPythonオブジェクトが消費するメモリ量を調査できます。sys.getsizeofとは対照的に、asizeofはオブジェクトを再帰的にサイズ設定します
from pympler import tracker
tr = tracker.SummaryTracker()
def fun():
li = [1,2,3]
di = {"ha":"haha","duh":"Umm"}
fun()
tr.print_diff()
関数の寿命を追跡します。
Pymplerパッケージは、コードをプロファイルするための非常に多くの高ユーティリティ関数で構成されています。ここではすべてをカバーすることはできません。詳細なプロファイルの実装については、添付のドキュメントを参照してください。
と呼ばれる統計プロファイラもありstatprof
ます。これはサンプリングプロファイラーであるため、コードに最小限のオーバーヘッドを追加し、(関数ベースだけでなく)行ベースのタイミングを提供します。ゲームなどのソフトリアルタイムアプリケーションに適していますが、cProfileよりも精度が低い場合があります。
pypiのバージョンは少し古いので、gitリポジトリをpip
指定してインストールできます。
pip install git+git://github.com/bos/statprof.py@1a33eba91899afe17a8b752c6dfdec6f05dd0c01
次のように実行できます。
import statprof
with statprof.profile():
my_questionable_function()
私は、pypref_timeからインスピレーションを得た独自のプロファイラーを開発しました。
https://github.com/modaresimr/auto_profiler
デコレータを追加すると、時間のかかる関数のツリーが表示されます
@Profiler(depth=4, on_disable=show)
Install by: pip install auto_profiler
import time # line number 1
import random
from auto_profiler import Profiler, Tree
def f1():
mysleep(.6+random.random())
def mysleep(t):
time.sleep(t)
def fact(i):
f1()
if(i==1):
return 1
return i*fact(i-1)
def show(p):
print('Time [Hits * PerHit] Function name [Called from] [Function Location]\n'+\
'-----------------------------------------------------------------------')
print(Tree(p.root, threshold=0.5))
@Profiler(depth=4, on_disable=show)
def main():
for i in range(5):
f1()
fact(3)
if __name__ == '__main__':
main()
Time [Hits * PerHit] Function name [Called from] [function location]
-----------------------------------------------------------------------
8.974s [1 * 8.974] main [auto-profiler/profiler.py:267] [/test/t2.py:30]
├── 5.954s [5 * 1.191] f1 [/test/t2.py:34] [/test/t2.py:14]
│ └── 5.954s [5 * 1.191] mysleep [/test/t2.py:15] [/test/t2.py:17]
│ └── 5.954s [5 * 1.191] <time.sleep>
|
|
| # The rest is for the example recursive function call fact
└── 3.020s [1 * 3.020] fact [/test/t2.py:36] [/test/t2.py:20]
├── 0.849s [1 * 0.849] f1 [/test/t2.py:21] [/test/t2.py:14]
│ └── 0.849s [1 * 0.849] mysleep [/test/t2.py:15] [/test/t2.py:17]
│ └── 0.849s [1 * 0.849] <time.sleep>
└── 2.171s [1 * 2.171] fact [/test/t2.py:24] [/test/t2.py:20]
├── 1.552s [1 * 1.552] f1 [/test/t2.py:21] [/test/t2.py:14]
│ └── 1.552s [1 * 1.552] mysleep [/test/t2.py:15] [/test/t2.py:17]
└── 0.619s [1 * 0.619] fact [/test/t2.py:24] [/test/t2.py:20]
└── 0.619s [1 * 0.619] f1 [/test/t2.py:21] [/test/t2.py:14]
サーバーのrootでない場合は、lsprofcalltree.pyを使用して、次の ようにプログラムを実行します。
python lsprofcalltree.py -o callgrind.1 test.py
次に、qcachegrindなどのcallgrind互換ソフトウェアでレポートを開くことができます