PythonのJITコンパイラまとめ: 3.13の実験導入から期待値の調整まで
Python 3.13 から、CPython に JIT コンパイラが実験的に入りました。「Python もついに JIT で速くなる」という記事の見出しを見たことがあるなら、期待値を一度点検する必要があります。入ったのは事実ですが、今すぐ体感できるほど速くなるわけではないからです。この記事では、JIT がどんな方式で動作するのか、どう有効にするのか、そして 2026 年半ば時点でどこまで来ているのかを整理します。
Faster CPython が作ってきた流れ #
「Python は遅い」という通念は古くからありますが、ここ数年の CPython は着実に速くなってきました。変化の中心には Faster CPython プロジェクトがありました。Python の生みの親グイド・ヴァンロッサムとマーク・シャノンが率いたこのチームの最初の大きな成果が、3.11 の特殊化適応型インタプリタ (PEP 659) です。同じバイトコードの位置に同じ型が繰り返し入ってくると、その位置を型専用の命令に差し替える方式です。これだけで 3.11 は 3.10 比で平均 1.25 倍速くなりました。
3.12 は内部構造を整え、3.13 でついに JIT が登場しました。特殊化が「インタプリタの中でできる最適化」だったとすれば、JIT はその次の段階である「機械語を直接作る最適化」です。
インタプリタと JIT の違い #
インタプリタはバイトコードを 1 個ずつ読み、そのたびに「この命令が何を意味するのか」を確認してから該当する C コードを実行します。毎回確認するコストが積み重なる構造です。
JIT (Just-In-Time) コンパイラは、実行中に頻繁に繰り返される区間を選び、その区間だけを機械語にしておきます。料理人が初めて見るメニューはレシピを 1 行ずつ確認しながら作るのに対し、毎日数百回出るメニューは手に馴染んでレシピを見ないのと似ています。頻繁に回るループほど「確認するコスト」をなくす効果が大きくなります。
Java の HotSpot、JavaScript の V8 が、この方式で動的言語を速くした代表例です。Python 陣営にも PyPy という JIT 実装が古くからありましたが、CPython 本体に JIT が入ったのは 3.13 が初めてです。
copy-and-patch: テンプレートをコピーして貼る JIT #
3.13 の JIT (PEP 744) は、copy-and-patch という手法を使います。2021 年のハオラン・シューとフレドリック・ショルスタッドの研究から出た、比較的新しい方式です。
伝統的な JIT は、ランタイムにコンパイラのインフラを丸ごと抱えています。中間表現を作り、最適化パスを回し、レジスタを割り当てて機械語を生成します。強力ですが、実装と保守の負担が大きいです。
copy-and-patch はアプローチが違います。
- ビルド時点: CPython をビルドするときに、各マイクロ命令に対応する機械語の断片、すなわちステンシル (stencil) を LLVM であらかじめ生成しておきます。
- 実行時点: 頻繁に回るコードパスが見つかると、該当するステンシルをメモリにコピー (copy) し、空いている穴に実際のアドレスと定数だけを埋めて (patch) つなぎ合わせます。
ランタイムにはコンパイラが不要で、機械語の生成が事実上「コピー + 穴埋め」なので非常に速いです。コード規模も小さく、少人数で保守できます。すべてのプラットフォームをサポートしなければならず、リリースサイクルが決まっている CPython にとって、このシンプルさは決定的な利点でした。3.13 で導入された Tier 2 マイクロ命令トレースの上にそのまま載る構造だという点も噛み合いました。
3.13 での有効化の方法 #
3.13 の公式配布バイナリには JIT が入っていません。自分でソースをビルドする必要があります。
./configure --enable-experimental-jit
makeビルドには含めつつ、デフォルトはオフにしておくオプションもあります。この場合、実行時点に環境変数で有効にします。
./configure --enable-experimental-jit=yes-off
make
# 実行するときだけ有効化
PYTHON_JIT=1 python myapp.pyWindows では PCbuild/build.bat --experimental-jit を使います。どちらにしても 3.13 で JIT を試すにはビルド環境を自分で整える必要があったため、事実上コア開発者とアーリーアダプターのための機能でした。
3.14 での状態 #
2025 年 10 月に出た 3.14 で、敷居が下がりました。公式の macOS・Windows インストーラに実験的 JIT ビルドが含まれるようになりました。依然としてデフォルトはオフで、環境変数で有効にします。
PYTHON_JIT=1 python myapp.py有効になっているかは、3.14 で追加された sys._jit 名前空間で確認できます。
import sys
print(sys._jit.is_available()) # このビルドに JIT が含まれているか
print(sys._jit.is_enabled()) # 今有効になっているか内部的にも、ホットパスの検出とメモリ使用が改善されました。ただし、1 つ区別すべき点があります。3.14 が 3.13 より全般的に速くなったのは事実ですが、その功績の大部分は JIT ではなく、インタプリタ自体の改善 (テールコールベースのインタプリタなど) にあります。JIT はまだ「デフォルトで有効にできるほど検証された高速化手段」ではなく、「公式バイナリに載って誰でも実験できるようになった機能」です。
現実チェック: 今どれくらい速くなるのか #
では、今 JIT を有効にするとどれくらい速くなるのでしょうか。正直な答えは「ほとんど差がない」です。
- 公式ドキュメントの表現自体が「一部のプログラムが速くなる可能性がある」であり、性能向上はまだ大きくないと明記しています。
- 公開されているベンチマークでは、JIT の効果は平均数パーセント水準で、ワークロードによってはかえって遅くなる場合もあります。3.14 リリース直後のミゲル・グリンバーグの測定でも、JIT ビルドは通常ビルドと意味のある差を示せませんでした。
- 短く実行されて終わるスクリプトや CLI ツールは、ウォームアップコストのために JIT が不利です。ホットループが十分に回って初めて、コンパイルされたコードが元を取れます。
これは失敗ではなく、予告されていた段階です。copy-and-patch の最初の目標は「今すぐ速い JIT」ではなく、「機械語生成の基盤を本体に安全に持ち込むこと」でした。土台の上に最適化を積む作業は、今進行中です。整理すると、現時点で JIT が意味を持つ対象は CPython 内部に関心のある開発者と、ベンチマークを自分で回してみたいユーザーであり、プロダクションサービスがこれでコストを削減できる段階ではありません。
既存の高速化手段との関係 #
「Python を速く」という要求自体は新しくなく、すでに検証された手段があります。
- PyPy: JIT を持つ別の Python 実装です。純粋な Python コードなら今でも CPython JIT と比較にならないほど速いですが、C 拡張の互換性が弱点です。
- Cython・mypyc: ホットスポットを C にコンパイルする方式です。
- Rust 拡張 (PyO3): 性能が重要な部分を Rust で書きます。
- NumPy のベクトル化: 数値計算なら、依然として最も効果の大きい選択です。
当面、実務の答えはそのままです。遅い箇所を測定で見つけ、その部分に上記の手段を適用することです。遅い箇所の見つけ方は、モダンPython上級 #7 で整理しました。CPython JIT の意味は、こうした迂回手段なしに「最新の Python を使うだけで速くなる」未来を本体の中で準備するところにあります。
free-threading との関係 #
「より速い Python」には 2 つの軸があります。シングルスレッドの実行速度を上げる JIT、そして複数のコアを同時に使えるようにする free-threading です。2 つは別々のプロジェクトで、進行速度も違います。free-threading は 3.14 で公式サポート段階 (PEP 779) に上がりましたが、JIT は依然として実験段階です。また、3.14 時点では free-threaded ビルドで JIT を併用できません。2 つの軸を 1 つのビルドで結合するのは、これからの課題です。
今後注視すべきこと #
変数が 1 つあります。2025 年 5 月、マイクロソフトが大規模な人員削減の過程で Faster CPython チームの大部分を解雇しました。プロジェクトを後援していた最大の推進力が抜けたことになります。ただし、JIT の開発自体はコア開発者とコミュニティ主導で続いており、3.14 の改善もその流れから出てきました。
今後確認すべき項目は 3 つです。
- 3.15 以降の性能曲線: 土台の上に積まれる最適化が、平均数パーセントの壁を越えるかが焦点です。
- デフォルト有効化の時期: 公式ビルドで JIT がデフォルトで有効になるバージョンが出れば、そのときが本当の転換点です。
- free-threading との結合: 2 つの軸が 1 つのビルドで一緒に動作して初めて、「速くて並列な Python」が完成します。
まとめ #
CPython 3.13 に copy-and-patch 方式の JIT が実験的に入り、3.14 からは公式の macOS・Windows インストーラで PYTHON_JIT=1 を付けるだけで試せるようになりました。ビルド時点に作っておいた機械語テンプレートをコピーして貼るシンプルな構造のおかげで、CPython が抱えられる形で入りましたが、現在の性能効果は平均数パーセント水準にとどまります。今は「有効にすれば速くなるスイッチ」ではなく、「これから速くなる基盤」と理解するのが正確です。当面の性能問題はプロファイリングと検証済みの高速化手段で解決し、JIT は 3.15 以降の性能曲線とデフォルト有効化の時期を基準に見守るのがよいでしょう。