JIT コンパイル

プログラムの実行時にコードをネイティブコードにコンパイルし、パフォーマンスを向上させる技術

ランタイムパフォーマンス

JIT コンパイルとは

JIT (Just-In-Time) コンパイルは、プログラムの実行時にバイトコードをネイティブコード (機械語) にコンパイルし、パフォーマンスを向上させる技術である。V8 (Node.js)、JVM (Java)、.NET CLR が JIT を使用する。

インタプリタ vs JIT vs AOT

インタプリタと JIT vs AOT の違いを以下にまとめる。

方式 コンパイル時期 速度
インタプリタ 実行時に逐次解釈 遅い Python (CPython)
JIT 実行時にコンパイル 速い V8, JVM
AOT 事前にコンパイル 最速 Rust, Go, GraalVM

V8 の JIT パイプライン

V8 の JIT パイプラインを図で示す。

JavaScript ソースコード
  ↓ パース
AST (抽象構文木)
  ↓ Ignition (インタプリタ)
バイトコード → 実行 (初回は遅い)
  ↓ ホットコードを検出
TurboFan (最適化 JIT コンパイラ)
  ↓ 最適化されたネイティブコード → 実行 (高速)
コンポーネント 役割
Ignition バイトコードインタプリタ (起動が速い)
TurboFan 最適化 JIT コンパイラ (実行が速い)

最適化と脱最適化

最適化と脱最適化のコード例を示す。

function add(a, b) { return a + b; }

// 最初の 100 回: a, b が常に number → TurboFan が number 専用コードを生成
add(1, 2);  // 高速 (最適化済み)

// 突然 string を渡す → 最適化が無効化 (脱最適化)
add("hello", "world");  // 遅い (インタプリタに戻る)

これが「単相性 (Monomorphism)」の重要性。同じ型を渡し続けると JIT が最適化できる。

Lambda でのコールドスタートと JIT

Lambda でのコールドスタートと JIT を図で示す。

コールドスタート:
  1. 実行環境の初期化
  2. コードのロード
  3. JIT コンパイル (初回は遅い)
  → 初回リクエストのレイテンシが増加

ウォームスタート:
  1. JIT コンパイル済みコードを再利用
  → 高速

SnapStart (Java Lambda)

Java Lambda の JIT コンパイル済み状態をスナップショットとして保存し、コールドスタートを高速化する。

AOT との比較

AOT との主な違いを以下に比較する。

観点 JIT (V8, JVM) AOT (Rust, Go)
起動速度 遅い (コンパイルが必要) 速い (コンパイル済み)
実行速度 高い (実行時最適化) 高い
メモリ 多い (コンパイラを含む) 少ない
Lambda 適性 コールドスタートが課題 コールドスタートが速い

さらに掘り下げるなら関連書籍が参考になる。

この記事は役に立ちましたか?

関連用語

関連する記事