プロファイリングとフレームグラフ
🐱 この章の目次
プロファイリングの種類
プロファイリング は、プログラムの実行時間がどこで消費されているかを特定する手法です。 大きく分けて サンプリング方式 と インストルメンテーション方式 の 2 種類があります。
| 方式 | 仕組み | オーバーヘッド | 用途 |
|---|---|---|---|
| サンプリング | 定期的にスタックトレースを取得 | 低い(1〜5%) | 本番環境での継続的プロファイリング |
| インストルメンテーション | 関数の入口/出口にフックを挿入 | 高い(10〜100%) | 開発環境での詳細解析 |
サンプリング方式は本番環境でも安全に使える点が大きなメリットです。
Python でのプロファイリング
Python では標準ライブラリの cProfile と、サンプリング型の py-spy が代表的なツールです。
# cProfile による関数単位の計測
import cProfile
import pstats
cProfile.run("main()", "output.prof")
stats = pstats.Stats("output.prof")
stats.sort_stats("cumulative")
stats.print_stats(20)
# py-spy でサンプリング(プロセスにアタッチ)
py-spy record -o profile.svg --pid 12345
py-spy は GIL を取得せずにスタックを読み取るため、対象プロセスへの影響が極めて小さいです。
フレームグラフ
フレームグラフ(flame graph) は Brendan Gregg が考案した、スタックトレースの集約を可視化する手法です。 横軸はサンプル数(時間の長さ)、縦軸はコールスタックの深さを表します。 幅の広い関数ほど CPU 時間を多く消費しており、最適化の対象候補です。
フレームグラフの読み方のポイントは以下のとおりです。
- 横軸の並び順にはアルファベット順が使われ、時系列ではない
- 「台地」状の平坦な幅広バーは、その関数自体が CPU を消費している
- 先端(上端)が尖っている部分は、深い呼び出しチェーンを示す
Off-CPU 分析
Off-CPU 分析 は、スレッドが CPU を使っていない時間(I/O 待ち、ロック待ち、スリープ)を可視化する手法です。 CPU プロファイルだけでは、I/O バウンドな問題を見逃してしまいます。 Off-CPU フレームグラフを併用することで、CPU 時間と待機時間の両面からボトルネックを特定できます。