- CPythonのテールコール型インタープリタが、Windows x86-64環境で従来方式より約15%高速な性能を示した
- macOS AArch64(XCode Clang)でも約5%の性能向上が確認され、WindowsではMSVC 2026の実験的機能を活用
- pyperformanceベンチマークでは大半のテストで高速化が見られ、一部は最大78%まで改善
- 性能向上の主因はコンパイラ最適化ヒューリスティクスのリセットとインライン化の改善と分析されている
- Python 3.15正式リリース時には、Visual Studio 2026ベースのビルドでデフォルト適用される予定
テールコール型インタープリタの性能改善
- CPythonのテールコール型インタープリタは、従来のswitch-caseインタープリタよりWindows x86-64で約15%高速と測定された
- pyperformance基準で幾何平均15〜16%向上
- 一部ベンチマークは最大78%高速化した一方、ごく少数では60%低速化
- macOS AArch64(XCode Clang)では約5%の性能向上を確認
- この結果は、Python 3.15の開発サイクル中に変更が入らないことを前提に有効
インタープリタ構造の比較
- Cベースのインタープリタ実装方式はswitch-case、computed goto、tail-call threadedの3種類に分けられる
- switch-case: 命令ごとに分岐処理
- computed goto: GCC/Clangの拡張機能で、分岐先アドレスへ直接ジャンプ
- tail-call threaded: 各バイトコードハンドラを関数に分離し、次の関数へテールコール
- 過去にはCコンパイラがテールコール最適化を保証しなかったため、スタックオーバーフローの危険があった
- Clangの
__attribute__((musttail))とMSVCの[[msvc::musttail]]属性により、強制テールコールが可能になった
Windows向けMSVC 2026ビルド結果
- MSVCの実験的機能を使ったCPythonビルドでは、ベンチマークの大半で高速化
- 結果例:
spectralnorm: 1.48倍
nbody: 1.35倍
bm_django_template: 1.18倍
xdsl: 1.14倍
- Python 3.15の「What’s New」ドキュメントにも正式に反映
- Visual Studio 2026(MSVC 18)ビルドでテールコール型インタープリタを利用可能
- 純粋なPythonライブラリでは約15%、小規模スクリプトでは最大40%高速化
性能向上の要因
- テールコールはコンパイラの最適化ヒューリスティクスを初期化し、より効率的なコード生成を促す
- 従来のCPythonインタープリタループは約12,000行の単一関数で構成されており、インライン化最適化の失敗が頻発
- コンパイラがコードサイズ増大を避けるため、インライン化を拒否するケースが多数
- テールコール方式では関数が分離され、単純な関数をインライン化できる
- 例として
PyStackRef_CLOSE_SPECIALIZEDのような単純な関数がインライン化される
- PGO(プロファイル誘導最適化)ビルドでも同様の現象が報告されている
ビルドと利用方法
- 現時点ではソースからのビルドのみ可能
- 今後、Python 3.15開発が安定すれば公式バイナリ配布の予定
1件のコメント
Hacker Newsのコメント
MSVCとClangにおける
musttailおよびpreserve_none属性定義の違いを示す例とのことこれらの属性は関数宣言子に付ける必要があり、関数指定子の位置では動作しない
関連コードへのリンク
Microsoftが重要だと判断したプロジェクトにだけこのような非公開機能を知らせているかのようなニュアンスがある
[[msvc::musttail]]は実際には正式に文書化された属性だったブログ記事を修正して反映する予定だという
関連するHNコメント
記事を読む限り、透明性と迅速なフィードバックを優先したアプローチなので問題なさそうだと判断している
クロスコンパイラでの検証や独立監査があればなお良いが、著者の完全な透明性のおかげで信頼できると見ている
早い段階で公開したおかげでNelsonがClang 19のバグを見つけ、本番リリース前に修正できた
今回はdispatchロジックとinliningという2つの改善があるので、より自信があるという
MSVCは特定条件下でswitch-caseインタプリタをthreaded codeに変換できるが、CPythonは複雑すぎてその最適化が適用されない
その代わり、tail callアプローチではCコードの作者がより多くの制御権を持てる
関連参考: MSVC threaded codeの条件, forceinline関連のissue
以前はtail duplicationのような最適化がコンパイラ判断次第で変わっていたが、今ではインタプリタ自身が望む機械語コードの形を直接表現できる
以前の議論へのリンク
C#/MAUIよりもVisual Studioのエコシステムが重すぎるのでPythonを選んだという
Tkinterは使いづらく、Qtは学習コストが高いため、wxGlade + wxPythonの組み合わせを使っている
pipでインストールできる単一の依存関係だけで済み、Pythonらしい使い心地が気に入っているWindowsランタイムの改善は歓迎とのこと
QtCreatorでUIを素早く作り、Pythonでロジックを載せれば開発速度が非常に速い
TkinterやQtのようなretained modeではなく、immediate mode方式なので内部ツール用途に特に有用だという
imgui_bundleプロジェクト
主要ISAごとにアセンブリで書かれているものだと思っていたという
[[msvc::musttail]]はMSVC 14.50(先月リリース)で追加された最新属性で、CPythonチームは数週間でこれを活用して性能向上を実現したMSVC musttailドキュメント
Guidoがコードの単純さを優先したためJIT導入は遅れ、その後PEP 744(JIT Compilation)のような試みが出てきた
アセンブリ最適化は保守性の悪夢であり、Pythonの本当のボトルネックはパッケージングシステムだ
PyPyはJITのおかげで速いが、C拡張と互換性がない
Pythonのスレッドモデルも最適化を難しくしている
一方でJSはシングルスレッドなので単純だ
PythonはC拡張で迂回できるため、CPython自体の最適化に対する圧力が弱かった
またCPythonは巨大なC拡張エコシステムのため互換性を壊せない
その一方でV8は内部構造を自由に変えられた
さらに安定したC ABIを維持しなければならず、JITが自由にコード解析するのが難しい
PyPyがこうした制約に対応するのに苦労した事例にも触れている
またJSは純粋なJSだけをサポートすればよいが、Pythonは外部拡張エコシステムを維持しなければならず、最適化の制約が多い
自分は
mitataでJSライブラリの性能を測った経験があると共有しているImmer JS最適化PR
Wikipediaの説明, Matplotlibの例
分布を対称に可視化するが、平滑化によって実際の分布が歪むことがあり、スペースの無駄だという批判もある
HNでの議論 ではhalf-violin plotのほうが良いという意見もあった
例の画像
AI文章の典型的な特徴(短い段落、過剰に前向きな口調、深みの不足など)を皮肉っている