私はコードをプロファイリングするためにcProfileを使用してきましたが、うまく機能しています。 gprof2dot.py を使用して、結果を視覚化します(わかりやすくします)。
ただし、cProfile(および他のほとんどのPython私がこれまで見たプロファイラー)は、関数呼び出しレベルでのみプロファイルするようです。これにより、特定の関数が異なる場所から呼び出されると混乱が生じます。呼び出し#1または呼び出し#2がほとんどの時間を占めているかどうかはわかりませんが、問題の関数が他の7つの場所から呼び出された6レベルの深さである場合、さらに悪化します。
行ごとのプロファイリングを取得するにはどうすればよいですか?
これの代わりに:
function #12, total time: 2.0s
私はこのようなものを見たいです:
function #12 (called from somefile.py:102) 0.5s
function #12 (called from main.py:12) 1.5s
cProfileは、合計時間のどれだけが親に「転送」されるかを示しますが、ここでも、多数のレイヤーと相互接続された呼び出しがあると、この接続は失われます。
理想的には、データを解析し、各行に合計時間を指定してソースファイルを表示するGUIが必要です。このようなもの:
main.py:
a = 1 # 0.0s
result = func(a) # 0.4s
c = 1000 # 0.0s
result = func(c) # 5.0s
次に、2番目の「func(c)」呼び出しをクリックして、「func(a)」呼び出しとは別に、その呼び出しで何が時間を消費しているかを確認できます。
それは理にかなっていますか?このタイプの情報を収集するプロファイリングライブラリはありますか?見逃した素晴らしいツールはありますか?
Robert Kernのline_profiler が意図していることだと思います。リンクから:
File: pystone.py
Function: Proc2 at line 149
Total time: 0.606656 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
149 @profile
150 def Proc2(IntParIO):
151 50000 82003 1.6 13.5 IntLoc = IntParIO + 10
152 50000 63162 1.3 10.4 while 1:
153 50000 69065 1.4 11.4 if Char1Glob == 'A':
154 50000 66354 1.3 10.9 IntLoc = IntLoc - 1
155 50000 67263 1.3 11.1 IntParIO = IntLoc - IntGlob
156 50000 65494 1.3 10.8 EnumLoc = Ident1
157 50000 68001 1.4 11.2 if EnumLoc == Ident1:
158 50000 63739 1.3 10.5 break
159 50000 61575 1.2 10.1 return IntParIO
お役に立てば幸いです!
pprofile ( pypi )を使用することもできます。実行全体のプロファイルを作成する場合、ソースコードの変更は必要ありません。次の2つの方法で、より大きなプログラムのサブセットをプロファイルすることもできます。
次のようなコード内の特定のポイントに到達したときにプロファイルを切り替えます。
import pprofile
profiler = pprofile.Profile()
with profiler:
some_code
# Process profile content: generate a cachegrind file and send it to user.
統計プロファイリングを使用して、コールスタックから非同期的にプロファイリングを切り替えます(たとえば、シグナルハンドラーまたは使用可能なワーカースレッドなど、対象のアプリケーションでこのコードをトリガーする方法が必要です)。
import pprofile
profiler = pprofile.StatisticalProfile()
statistical_profiler_thread = pprofile.StatisticalThread(
profiler=profiler,
)
with statistical_profiler_thread:
sleep(n)
# Likewise, process profile content
コード注釈の出力形式は、ラインプロファイラーによく似ています。
$ pprofile --threads 0 demo/threads.py
Command line: ['demo/threads.py']
Total duration: 1.00573s
File: demo/threads.py
File duration: 1.00168s (99.60%)
Line #| Hits| Time| Time per hit| %|Source code
------+----------+-------------+-------------+-------+-----------
1| 2| 3.21865e-05| 1.60933e-05| 0.00%|import threading
2| 1| 5.96046e-06| 5.96046e-06| 0.00%|import time
3| 0| 0| 0| 0.00%|
4| 2| 1.5974e-05| 7.98702e-06| 0.00%|def func():
5| 1| 1.00111| 1.00111| 99.54%| time.sleep(1)
6| 0| 0| 0| 0.00%|
7| 2| 2.00272e-05| 1.00136e-05| 0.00%|def func2():
8| 1| 1.69277e-05| 1.69277e-05| 0.00%| pass
9| 0| 0| 0| 0.00%|
10| 1| 1.81198e-05| 1.81198e-05| 0.00%|t1 = threading.Thread(target=func)
(call)| 1| 0.000610828| 0.000610828| 0.06%|# /usr/lib/python2.7/threading.py:436 __init__
11| 1| 1.52588e-05| 1.52588e-05| 0.00%|t2 = threading.Thread(target=func)
(call)| 1| 0.000438929| 0.000438929| 0.04%|# /usr/lib/python2.7/threading.py:436 __init__
12| 1| 4.79221e-05| 4.79221e-05| 0.00%|t1.start()
(call)| 1| 0.000843048| 0.000843048| 0.08%|# /usr/lib/python2.7/threading.py:485 start
13| 1| 6.48499e-05| 6.48499e-05| 0.01%|t2.start()
(call)| 1| 0.00115609| 0.00115609| 0.11%|# /usr/lib/python2.7/threading.py:485 start
14| 1| 0.000205994| 0.000205994| 0.02%|(func(), func2())
(call)| 1| 1.00112| 1.00112| 99.54%|# demo/threads.py:4 func
(call)| 1| 3.09944e-05| 3.09944e-05| 0.00%|# demo/threads.py:7 func2
15| 1| 7.62939e-05| 7.62939e-05| 0.01%|t1.join()
(call)| 1| 0.000423908| 0.000423908| 0.04%|# /usr/lib/python2.7/threading.py:653 join
16| 1| 5.26905e-05| 5.26905e-05| 0.01%|t2.join()
(call)| 1| 0.000320196| 0.000320196| 0.03%|# /usr/lib/python2.7/threading.py:653 join
Pprofileはコード変更に依存しないため、プログラムの起動時間(モジュールのインポート、グローバルの初期化などにかかる時間)をプロファイルできるように、トップレベルのモジュールステートメントをプロファイルできます。
Cachegrind形式の出力を生成できるため、 kcachegrind を使用して大きな結果を簡単に参照できます。
開示:私はpprofileの著者です。
PyVmMonitorには、そこで役立つライブビューがあります(実行中のプログラムに接続して、そこから統計を取得できます)。
あなたはline_profilerパッケージの助けを借りることができます
1。パッケージの最初のインストール:
pip install line_profiler
2。magicコマンドを使用して、python/notebook環境にパッケージをロードします
%load_ext line_profiler
。関数のコードをプロファイルする場合は、
次のようにします。%lprun -f function_name function_call
%lprun -f function_defined_by_you function_defined_by_you(arg1, arg2)
上記の手順を実行すると、すべての詳細を含むフォーマットされた素敵な出力が得られます