コンパイルとインタプリタ
人が書いたソースコードを、コンピュータが実行できる形へ変換する方式の違いです。事前に機械語へ翻訳するか、その場で1行ずつ解釈するかで、速度と配布のしやすさが変わります。
- 1.コンパイルは実行前にソース全体を機械語へ翻訳し、インタプリタは実行時に1行ずつ解釈して動かします。
- 2.コンパイルは実行が速い反面ビルドが要り、インタプリタは手軽で柔軟だが実行は遅めという傾向があります。
- 3.JIT は実行しながら必要な部分を機械語化し、AOT は事前に機械語化することで両者の利点を取り込みます。
なぜ「翻訳」が必要か
私たちが書くソースコードは、人間に読みやすい文法でできています。しかし CPU が直接理解できるのは、0 と 1 の並びである機械語だけです。そのため、ソースコードを機械語へ変換する作業が必ずどこかで必要になります。この変換をいつ・どのように行うかが、コンパイルとインタプリタの分かれ目です。
- コンパイル方式 — 実行する前に、ソース全体をまとめて機械語へ翻訳しておきます。
- インタプリタ方式 — 実行するそのときに、ソースを1行ずつ読んで解釈しながら動かします。
レストランに例えるなら、コンパイルは「料理をすべて作り置きしてから配膳する」方式、インタプリタは「注文が入るたびにその場で1品ずつ作る」方式です。どちらも料理は出てきますが、待ち時間や柔軟さの性質が異なります。
2方式の比較
両者は速度・配布・柔軟性の面で対照的な特徴を持ちます。優劣ではなく、用途に応じたトレードオフです。
| 観点 | コンパイル方式 | インタプリタ方式 |
|---|---|---|
| 翻訳のタイミング | 実行前に一括 | 実行時に逐次 |
| 実行速度 | 速い(機械語を直接実行) | 遅め(毎回解釈が入る) |
| 起動・修正の手軽さ | ビルドの手間がかかる | すぐ動かせて試行錯誤が速い |
| 配布 | 実行ファイル単体で動く | 実行環境(処理系)が必要 |
| エラー検出 | 実行前にまとめて検出 | 走らせた行で初めて顕在化 |
代表例として、C や C++、Rust、Go はコンパイル方式、Python や Ruby、PHP、シェルスクリプトはインタプリタ方式に分類されます。ただし、後述するように現実の処理系は両者を組み合わせることが多く、「この言語は完全にこちら」と単純に割り切れない点には注意が必要です。
コンパイル: ソース → [コンパイラ] → 機械語の実行ファイル → 実行
インタプリタ: ソース → [インタプリタが1行ずつ解釈しながら実行]
中間コードと仮想マシン
Java や C# は、この2つのちょうど中間にあたる方式を採ります。まずソースを**中間コード(バイトコード)にコンパイルし、それを仮想マシン(VM)**が解釈・実行します。
- 中間コードは特定の CPU に依存しないため、同じ成果物がどの環境でも動かせます(Java の "Write Once, Run Anywhere")。
- VM が橋渡しをすることで、OS や CPU の違いを吸収できます。
- 完全な機械語ほど速くはありませんが、純粋なインタプリタよりは効率的です。
この「いったん中間コードにする」発想が、次に述べる JIT の前提になります。
JIT と AOT
中間コードやインタプリタの「遅さ」を補うのが、**JIT(Just-In-Time)とAOT(Ahead-Of-Time)**という2つのコンパイル戦略です。
| 方式 | 翻訳のタイミング | ねらい |
|---|---|---|
| JIT | 実行中、よく使う箇所をその場で機械語化 | 起動の手軽さと実行速度の両立 |
| AOT | 配布前にあらかじめ機械語化 | 起動の速さと配布物の自己完結 |
JIT は、プログラムを動かしながら「何度も実行される重い部分(ホットスポット)」を検出し、そこだけを実行時に機械語へ変換してキャッシュします。実行回数の多いコードが繰り返すうちに速くなるのが特徴で、Java の HotSpot VM や JavaScript エンジン(V8 など)が採用しています。一方の AOT は、実行前に機械語化を済ませる点でコンパイル方式に近く、起動が速く配布も簡単になります。
「コンパイル言語/インタプリタ言語」という区分は、厳密には言語ではなく**処理系(実装)**の性質です。たとえば Python は通常バイトコードへコンパイルしてから VM が実行し、Java は JIT を使い、Rust は AOT に近いコンパイルを行います。「その言語をどう動かしているか」で実態は変わると捉えると、混乱しにくくなります。
コンパイル方式は型の不一致などを実行前に弾けるのが強みですが、それは文法や型のレベルの誤りを見つけるだけです。ロジックの間違いはコンパイルが通っても残ります。逆にインタプリタ方式は、実行して初めてエラーが出る行があり得るため、テストで全経路を通すことがより重要になります。
まとめ
ソースを機械語へ変換するタイミングが、コンパイル(実行前に一括)とインタプリタ(実行時に逐次)の本質的な違いです。前者は実行が速く配布が容易な反面ビルドが要り、後者は手軽で柔軟だが実行は遅めというトレードオフになります。現実の処理系は、中間コードと仮想マシン、実行中に最適化する JIT、事前に機械語化する AOT を組み合わせ、両者の利点を取り込んでいます。「言語=方式」と決めつけず、「その処理系がどう動かしているか」で捉えるのが理解の近道です。
プログラミング Article
コンパイルとインタプリタを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
コンパイラ
比較で見る軸
難易度: basic / カテゴリ: プログラミング / タグ数: 3
導入後に効く点
コンパイルは実行が速い反面ビルドが要り、インタプリタは手軽で柔軟だが実行は遅めという傾向があります。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- basic
- カテゴリ
- プログラミング
- タグ数
- 3
判断チェックリスト
- 自社の用途が「コンパイラ / インタプリタ」に近いか確認する。
- 強みである「コンパイルは実行前にソース全体を機械語へ翻訳し、インタプリタは実行時に1行ずつ解釈して動かします。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。