3 ポイント 投稿者 GN⁺ 2025-12-26 | 1件のコメント | WhatsAppで共有
  • 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-casecomputed gototail-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(プロファイル誘導最適化)ビルドでも同様の現象が報告されている

ビルドと利用方法

  • 現時点ではソースからのビルドのみ可能
    • Visual Studio 2026環境で次のコマンドによりビルド
      $env:PlatformToolset = "v145"
      ./PCbuild/build.bat --tail-call-interp -c Release -p x64 --pgo
      
  • 今後、Python 3.15開発が安定すれば公式バイナリ配布の予定

1件のコメント

 
GN⁺ 2025-12-26
Hacker Newsのコメント
  • ブログ記事に入っていてほしかった重要なコード断片を共有している
    MSVCとClangにおける musttail および preserve_none 属性定義の違いを示す例とのこと
    これらの属性は関数宣言子に付ける必要があり、関数指定子の位置では動作しない
    関連コードへのリンク
    Microsoftが重要だと判断したプロジェクトにだけこのような非公開機能を知らせているかのようなニュアンスがある
    • 自分の勘違いだった。[[msvc::musttail]] は実際には正式に文書化された属性だった
      ブログ記事を修正して反映する予定だという
      関連するHNコメント
    • 「重要だから教えたのか、それとも自分たちの利益になるから教えたのか?」という疑問を呈している
  • 以前のPython 3.14のときのように、LLVM 19のバグによって誤った性能向上が報告された事例を思い出し、今回はそういう問題がないことを願っている
    記事を読む限り、透明性と迅速なフィードバックを優先したアプローチなので問題なさそうだと判断している
    クロスコンパイラでの検証や独立監査があればなお良いが、著者の完全な透明性のおかげで信頼できると見ている
    • 筆者はそのときのミスをむしろ幸運な事故だったと振り返っている
      早い段階で公開したおかげでNelsonがClang 19のバグを見つけ、本番リリース前に修正できた
      今回はdispatchロジックとinliningという2つの改善があるので、より自信があるという
      MSVCは特定条件下でswitch-caseインタプリタをthreaded codeに変換できるが、CPythonは複雑すぎてその最適化が適用されない
      その代わり、tail callアプローチではCコードの作者がより多くの制御権を持てる
      関連参考: MSVC threaded codeの条件, forceinline関連のissue
    • 新設計の利点は、コンパイラ最適化の気まぐれに左右されにくい点だとしている
      以前はtail duplicationのような最適化がコンパイラ判断次第で変わっていたが、今ではインタプリタ自身が望む機械語コードの形を直接表現できる
      以前の議論へのリンク
  • 過去のコンパイラ問題を扱った発表があるとして、EuroPython 2025の講演動画 を共有している
  • 久しぶりにWindows向けGUIアプリをPythonで作っている
    C#/MAUIよりもVisual Studioのエコシステムが重すぎるのでPythonを選んだという
    Tkinterは使いづらく、Qtは学習コストが高いため、wxGlade + wxPythonの組み合わせを使っている
    pip でインストールできる単一の依存関係だけで済み、Pythonらしい使い心地が気に入っている
    Windowsランタイムの改善は歓迎とのこと
    • 自分はPython + Qt/PySide の組み合わせが好みだ
      QtCreatorでUIを素早く作り、Pythonでロジックを載せれば開発速度が非常に速い
    • pyfltk も勧めている。GNU/Linuxではかなり良かったという
    • GUIが重要ならLINQPadも検討に値する。スクリプティングと重い開発環境の中間にある
    • Python向けのImGuiバインディングを勧めている
      TkinterやQtのようなretained modeではなく、immediate mode方式なので内部ツール用途に特に有用だという
      imgui_bundleプロジェクト
  • 「この程度なら難易度の低い最適化課題ではないのか」として、なぜインタプリタループがまだ完全に最適化されていないのか疑問を投げかけている
    主要ISAごとにアセンブリで書かれているものだと思っていたという
    • むしろ今回の更新は、ループがすでに極度に最適化されていることを示していると考えている
      [[msvc::musttail]] はMSVC 14.50(先月リリース)で追加された最新属性で、CPythonチームは数週間でこれを活用して性能向上を実現した
      MSVC musttailドキュメント
    • Pythonはもともと速度より単純さを重視している
      Guidoがコードの単純さを優先したためJIT導入は遅れ、その後PEP 744(JIT Compilation)のような試みが出てきた
    • オープンソースに過度な期待をしてはいけない
      アセンブリ最適化は保守性の悪夢であり、Pythonの本当のボトルネックはパッケージングシステムだ
    • そもそも性能に敏感な人はWindowsでPythonを動かさないとも述べている
  • 「なぜPythonインタプリタはV8よりはるかに遅いのか?」という質問が出ている
    • JavaScriptはJITコンパイルを使うが、CPythonはそうではない
      PyPyはJITのおかげで速いが、C拡張と互換性がない
      Pythonのスレッドモデルも最適化を難しくしている
      一方でJSはシングルスレッドなので単純だ
      PythonはC拡張で迂回できるため、CPython自体の最適化に対する圧力が弱かった
    • Googleの人員と品質が大きな差を生んでいると見る向きもある
      またCPythonは巨大なC拡張エコシステムのため互換性を壊せない
      その一方でV8は内部構造を自由に変えられた
    • Pythonは属性アクセスですら descriptorプロトコル を通るなど、はるかに動的
      さらに安定したC ABIを維持しなければならず、JITが自由にコード解析するのが難しい
    • PythonはJSよりずっと動的な言語で、FFIバインディングのため内部変更にも制約がある
      PyPyがこうした制約に対応するのに苦労した事例にも触れている
    • JSはGoogleがWebを支配するため莫大な資源を投入して最適化してきたが、Pythonは言語の発展により多くのリソースを使ってきた
      またJSは純粋なJSだけをサポートすればよいが、Pythonは外部拡張エコシステムを維持しなければならず、最適化の制約が多い
  • 新しいベンチマークグラフが興味深いとして、どのツールで生成したのか尋ねている
    自分は mitata でJSライブラリの性能を測った経験があると共有している
    Immer JS最適化PR
    • そのグラフはバイオリンプロット
      Wikipediaの説明, Matplotlibの例
      分布を対称に可視化するが、平滑化によって実際の分布が歪むことがあり、スペースの無駄だという批判もある
      HNでの議論 ではhalf-violin plotのほうが良いという意見もあった
      例の画像
  • Matt Godboltが、tail-callベースのインタプリタはCPUの**分岐予測器(branch predictor)**により適していると述べていたことを伝えている
  • 記事の最初の文に誤字が2つあるが、もしかしてAI生成っぽさを出すための意図的なミスなのかと尋ねるコメントがある
    • 筆者は「ありがとう、直した」と返答している
    • 別のユーザーは、「AIっぽく見せたくないなら、ただ自分で書けばいい」と冗談めかして助言している
      AI文章の典型的な特徴(短い段落、過剰に前向きな口調、深みの不足など)を皮肉っている
  • 「Pythonチームがtail callを有用だと考えているなら、言語自体にもtail callサポートが入るのか?」という質問を投げている