2026-10-12 · ← ニュース
Python 3.15が隠れたボトルネックを可視化。sampleの95.1%はmain thread外にあった
Simon WillisonがPython 3.15の新しいsampling profilerをweb-editに使ったところ、記録されたstackの95.1%がworker thread由来だった。組み込みprofilerの実用性と、計測範囲を誤れば見栄えのよい可視化でもほぼ全処理を見逃す危険を同時に示す例だ。
画像を読み込めませんでした。
Simon Willisonは、GPT-6 Astra Extra Highを使うCodexに、Python 3.15の新しいsampling profilerをweb-editで試すdemoの作成を依頼した。未変更のappから15,296件のCPU stackが記録され、preserve_endingsは64.8%に現れた。SequenceMatcher.find_longest_matchはleaf sampleの38.3%を占めた。
一つのoptionがworker thread内の95.1%の処理を見つけた
全threadをsampleすることが決定的だった。AnyIOのworker threadが記録stackの95.1%を生み、main threadだけのprofileでは最大のコストを見逃していた。結果は、負荷の高い編集処理で異なる改行コードの維持が支配的だったことを示した。
Python 3.15は二つの手法を持つprofiling packageを追加した。profiling.samplingはstackを定期的に取得し、flame graph、heatmap、GIL分析、PIDによる実行中processへの接続に対応する。profiling.tracingは全てのcall、return、exceptionを追い、より大きなoverheadと引き換えに正確なcall数を出す。
標準libraryのprofilerが違和感から該当codeまでの距離を縮める
flame graphはcall階層を示し、source heatmapは具体的な行を示す。開発者は、漠然とした遅さから特定のfunctionへ進むために、複数の外部toolを最初から組み合わせる必要がない。sampling profilerは再起動やcode変更なしで実行中processにも接続できる。
Willisonの手順にはもう一つ意味がある。coding agentは最初にtoolを調査し、その後で再現可能なdemoを作るよう指示された。source codeを読んだだけで性能を推測したのではない。計測toolを操作し、人間が開いて疑える成果物を返した。
鮮やかなgraphでも間違った問いには正確に答えてしまう
samplingが返すのは統計的な推定であり、正確なcall数ではない。短いfunctionはsample間で消えることがある。公式documentもprofilingとbenchmarkingを明確に分けている。正確なcall数にはtracingがあり、小さなcode片の時間計測にはtimeitがある。
最大の警告は95.1%という数字そのものだ。thread、mode、workloadの選択を誤れば、toolは救ってくれない。人間が現実的なscenarioを定義し、取得範囲を確認しなければ、agentは完璧なflame graphで脇役の処理を分析できてしまう。
修正前後を再現できるprofileが価値を決める
次にするべきことはheatmapを眺めることではなく、preserve_endingsを変更して同じworkloadを繰り返すことだ。新しいprofileでsampleの分布が移り、改行処理の正しさも維持されて初めて改善と言える。
agentがcommand、Python version、profiler設定、test workloadを記録するかも重要だ。これらがなければ、画像はカルテのない診断にすぎない。
Lilithの判定
このflame graphで最も重要な部分は、全threadを測らなければ消えていた処理だ。agentは虫眼鏡を持てても、どこへ向けるかは人間が決める。
外部リンクは最後に置いています。まずここで簡潔に解説 — 他人のサイトを探し回る必要はありません。
元の記事 ↗ ↗