pstats --- プロファイラの統計

ソースコード: Lib/pstats.py


pstats モジュールは、Python のプロファイラが生成したプロファイリング統計を読み込み、操作し、表示するためのツールを提供します。 profiling.tracing (決定論的プロファイラ) と profiling.sampling (統計的プロファイラ) の両方の出力を読み込めます。

プロファイルデータの読み込みと表示

Stats クラスは、プロファイルデータを扱うための主なインターフェースです。 ファイルから、または Profile オブジェクトから直接、統計を読み込めます。

ファイルから統計を読み込み、基本的なレポートを表示します。

import pstats

p = pstats.Stats('profile_output.prof')
p.print_stats()

Stats オブジェクトには、表示前にデータをソートしたり絞り込んだりするメソッドがあります。 例えば、累積時間が最も長い 10 個の関数を表示するには、次のようにします。

from pstats import SortKey

p = pstats.Stats('profile_output.prof')
p.sort_stats(SortKey.CUMULATIVE).print_stats(10)

統計の操作

Stats クラスはメソッドチェーンをサポートしているので、複数の操作を簡単につなげられます。

p = pstats.Stats('restats')
p.strip_dirs().sort_stats(-1).print_stats()

strip_dirs() メソッドはファイル名からディレクトリパスを取り除き、出力をコンパクトにします。 sort_stats() メソッドには、ソート順を制御するさまざまなキーを指定できます。

ソートキーを変えると、性能の異なる側面に着目できます。

from pstats import SortKey

# 累積時間が最も長い関数
p.sort_stats(SortKey.CUMULATIVE).print_stats(10)

# 関数自身のコードの実行時間が最も長い関数
p.sort_stats(SortKey.TIME).print_stats(10)

# 名前順にソートした関数
p.sort_stats(SortKey.NAME).print_stats()

出力の絞り込み

print_stats() メソッドは、表示する関数を絞り込む制限条件を受け取ります。 制限条件には、整数 (件数の上限)、0 から 1 の浮動小数点数 (選択する割合)、文字列 (関数名との正規表現による照合) を指定できます。

上位 10% だけを表示します。

p.print_stats(.1)

名前に "init" を含む関数だけを表示します。

p.print_stats('init')

制限条件を組み合わせます (順番に適用されます)。

# 上位 10% に絞り、その中で "init" を含むものだけを表示する。
p.print_stats(.1, 'init')

# "foo:" に一致するファイル内の関数を、上位 50% に絞る。
p.sort_stats(SortKey.FILENAME).print_stats('foo:', .5)

呼び出し関係の分析

print_callers() メソッドは、表示する各関数がどの関数から呼び出されたかを示します。

p.print_callers()

print_callees() メソッドは逆の関係、つまり表示する各関数が呼び出した関数を列挙します。

p.print_callees()

どちらのメソッドも、print_stats() と同じ制限条件の引数を受け取ります。

複数のプロファイルの統合

複数回のプロファイリングの統計を 1 つの Stats オブジェクトに統合できます。

# 複数のファイルを一度に読み込む。
p = pstats.Stats('run1.prof', 'run2.prof', 'run3.prof')

# または、ファイルを順次追加する。
p = pstats.Stats('run1.prof')
p.add('run2.prof')
p.add('run3.prof')

ファイルを統合すると、同じ関数 (ファイル、行番号、名前が同じもの) の統計が合算され、すべてのプロファイリング実行をまとめて把握できます。

Stats クラス

class pstats.Stats(*filenames_or_profile, stream=sys.stdout)

プロファイルデータから統計オブジェクトを作成します。

The arguments can be filenames (strings or path-like objects) or Profile objects. If multiple sources are provided, their statistics are combined.

stream 引数は、print_stats() および関連メソッドの出力先を指定します。 デフォルトは sys.stdout です。

プロファイルデータの形式は、生成した Python のバージョンに固有です。 異なる Python バージョン間や異なるプロファイラ間での互換性は保証されません。

strip_dirs()

すべてのファイル名から先頭のパス情報を取り除きます。

このメソッドはオブジェクトを直接変更し、メソッドチェーンのためにそのオブジェクトを返します。 パス情報の除去後、統計の順序は不定とみなされます。

パス情報を取り除いた結果、2 つの関数が区別できなくなる (ファイル名、行番号、関数名が同じになる) 場合、その統計は 1 つのエントリに統合されます。

add(*filenames)

追加のファイルからプロファイリングデータを加えます。

ファイルは同じ種類のプロファイラで作成されていなければなりません。 同じ関数の統計は合算されます。

dump_stats(filename)

現在の統計をファイルに保存します。

ファイルがなければ作成し、あれば上書きします。 保存したデータは、新しい Stats オブジェクトを作成して読み込めます。

sort_stats(*keys)

指定した基準に従って統計をソートします。

各キーには文字列または SortKey 列挙型のメンバーを指定できます。 複数のキーを指定すると、先のキーで同順位となった項目を後のキーで並べます。

より適切にエラーを検出できるため、文字列よりも SortKey 列挙型のメンバーを使うことを推奨します。

from pstats import SortKey
p.sort_stats(SortKey.CUMULATIVE)

使用できるソートキー:

文字列

列挙型

意味

'calls'

SortKey.CALLS

呼び出し数

'cumulative'

SortKey.CUMULATIVE

累積時間

'cumtime'

N/A

累積時間

'file'

N/A

ファイル名

'filename'

SortKey.FILENAME

ファイル名

'module'

N/A

ファイル名

'ncalls'

N/A

呼び出し数

'pcalls'

SortKey.PCALLS

プリミティブな呼び出し回数

'line'

SortKey.LINE

行番号

'name'

SortKey.NAME

関数名

'nfl'

SortKey.NFL

関数名/ファイル名/行番号

'stdname'

SortKey.STDNAME

標準名

'time'

SortKey.TIME

内部時間

'tottime'

N/A

内部時間

統計値によるソートはすべて降順 (時間が最もかかったものが先) ですが、名前、ファイル、行番号によるソートは昇順 (名前はアルファベット順) です。

SortKey.NFL と SortKey.STDNAME の違いは、NFL が行番号を数値としてソートするのに対し、STDNAME は文字列としてソートすることです。 sort_stats(SortKey.NFL) は sort_stats(SortKey.NAME, SortKey.FILENAME, SortKey.LINE) と等価です。

後方互換性のため、数値の引数 -1、0、1、2 も受け付けます。 それぞれ 'stdname'、'calls'、'time'、'cumulative' を意味します。

Added in version 3.7: SortKey 列挙型。

reverse_order()

現在のソート順を逆にします。

デフォルトでは、ソートキーに適した方向 (時間のキーは降順、名前のキーは昇順) が選ばれます。 このメソッドはその方向を反転します。

print_stats(*restrictions)

プロファイリング統計のレポートを表示します。

出力にはデータの概要を示すヘッダー行と、その後に直近の sort_stats() 呼び出しに従ってソートした関数の統計表が含まれます。

制限条件で出力を絞り込みます。 各条件は次のいずれかです。

  • 整数: 出力するエントリ数を制限します。

  • 0.0 から 1.0 の浮動小数点数: エントリのうち指定した割合を選びます。

  • 文字列: 関数名と正規表現で照合します。

制限条件は順番に適用されます。 例えば、次のようにします。

print_stats(.1, 'foo:')

まず上位 10% に絞り込み、その中から 'foo:' に一致する関数を選びます。

print_callers(*restrictions)

統計内の各関数の呼び出し元を表示します。

絞り込んだ結果の各関数について、どの関数が何回呼び出したかを示します。

profiling.tracing (または cProfile) では、呼び出し元の各行に 3 つの数値が表示されます。 その呼び出し元からの呼び出し回数と、それらの呼び出しの合計時間および累積時間です。

print_stats() と同じ制限条件の引数を受け取ります。

print_callees(*restrictions)

統計内の各関数が呼び出した関数を表示します。

print_callers() の逆で、列挙された各関数がどの関数を呼び出したかを示します。

print_stats() と同じ制限条件の引数を受け取ります。

get_stats_profile()

統計を含む StatsProfile オブジェクトを返します。

返されるオブジェクトを使うと、プログラムからプロファイルデータにアクセスできます。 関数名は、時間と呼び出し回数の情報を持つ FunctionProfile オブジェクトに対応付けられています。

Added in version 3.9.

class pstats.SortKey

Stats.sort_stats() で使えるソートキーの列挙型です。

CALLS

呼び出し回数でソートします。

CUMULATIVE

累積時間でソートします。

FILENAME

ファイル名でソートします。

LINE

行番号でソートします。

NAME

関数名でソートします。

NFL

名前、ファイル、行番号の順にソートします (行番号は数値としてソートします)。

PCALLS

プリミティブな (再帰でない) 呼び出し回数でソートします。

STDNAME

標準名でソートします (行番号は文字列としてソートします)。

TIME

内部時間 (サブ呼び出しを除く関数内の時間) でソートします。

コマンドライン・インターフェース

pstats モジュールをスクリプトとして実行すると、プロファイルデータを対話的に調べられます。

python -m pstats profile_output.prof

統計を調べるための、cmd を使った行単位のインターフェースが開きます。 プロンプトで help と入力すると、利用できるコマンドが表示されます。

参考

profiling

Python のプロファイリングツールの概要。

profiling.tracing

決定論的トレースプロファイラ。

profiling.sampling

統計的サンプリングプロファイラ。