"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"
     統計的サンプリングプロファイラ。
