最終更新:

コンパイラとインタプリタの違い — 「変換する」と「実行する」を図解


「変換」と「実行」は組み合わせられる

Javaの基本手順ソースjavacclassJVMで実行一般的なCPythonソース変換バイトコードインタプリタで実行
青は入力、橙は変換後の形式、緑は実行です。JVMやV8などではJITも組み合わせます。図は処理速度の優劣を示していません。
ひよこ ひよこ
コードを書いたのに、そのままCPUが読めるわけじゃないんだよね?
ペンギン先生 ペンギン先生
そうだね。ソースコードを実行できる形にする仕組みが必要だよ。コンパイラはコードを別の形式へ変換するもの、インタプリタは命令を解釈して実行するもの。現実の実行環境では、この2つを組み合わせることも多いんだ。
ひよこ ひよこ
コンパイラは、本をまとめて翻訳する感じ?
ペンギン先生 ペンギン先生
別の形式へ翻訳するという意味では似ているよ。ただし出力は機械語だけとは限らない。Cなどから機械語へ進む例も、JavaのソースからJVM向けのクラスファイルへ変換する例もあるんだ。
ひよこ ひよこ
インタプリタは一行ずつ訳すの?
ペンギン先生 ペンギン先生
「命令を読み取って実行する係」と考えよう。ソースの各行を毎回そのまま翻訳するとは限らないんだ。一般的なCPythonも、ソースをバイトコードへコンパイルしてから、それを実行する仕組みを持っているよ。
ひよこ ひよこ
じゃあ、コンパイラ方式とインタプリタ方式で言語を二分できないの?
ペンギン先生 ペンギン先生
言語のルールと、その実装の動かし方は分けると正確だよ。同じ言語にも異なる実装がある。JavaScriptのV8では、バイトコードを扱うインタプリタと、実行中に機械語を生成するコンパイラを組み合わせているよ。
ひよこ ひよこ
実行中にコンパイルするのがJITなんだね?
ペンギン先生 ペンギン先生
そうだよ。JITはJust-In-Timeで、実行時にコードをコンパイルする方法だよ。一方、AOTは実行より前にコンパイルする方法。インタプリタから実行を始め、必要に応じてJITで最適化する環境もあるんだ。
ひよこ ひよこ
コンパイルするほうが、いつも速いの?
ペンギン先生 ペンギン先生
それだけでは決められないよ。変換や起動にかかる時間、繰り返す処理、外部ライブラリ、I/Oなどで違う。長く動く処理の速さと、起動してすぐの応答も別だから、実際の用途に合った測定が必要だね。
ひよこ ひよこ
エラーが見つかるタイミングも違う?
ペンギン先生 ペンギン先生
変換時に構文や型の問題を見つける環境はあるけれど、コンパイルできても実行時のエラーは起こるよ。逆にインタプリタを使う環境でも、実行に入る前に構文エラーを見つけることがある。「その行に来るまで何も分からない」とは限らないんだ。
ひよこ ひよこ
最初は何を覚えればいいかな?
ペンギン先生 ペンギン先生
「何から何へ変換するか」と「何が命令を実行するか」を分けて見よう。Javaのjavacとjava、Pythonのソースとバイトコードの例を読むとつながるよ。言語選びはこの分類だけで決めず、作りたいものや利用する道具も考えようね。

「変換」と「実行」を別の仕事として見る

図のファイルは変換でできるもの、矢印はその変換、実行環境は命令を動かすものです。コンパイラとインタプリタは、言語の人気や優劣の名前ではありません。

例変換・実行の見方
Javaの基本的な手順javac がソースをクラスファイルへ変換し、java でJVMを起動して実行する
一般的なCPythonソースからバイトコードを作る工程があり、インタプリタがそれを実行する
V8のJavaScriptインタプリタと複数のコンパイラを組み合わせる。すべての処理が常に同じ段階を通るわけではない

Javaのクラスファイルは、CPU用の機械語そのものではありません。対応するバージョンのJVMや必要なライブラリがあることが実行の条件です。ネイティブ依存などがあれば、OSをまたいでそのまま動かせない場合もあります。

Pythonがあるなら、バイトコードをのぞいてみる

次を peek.py として保存し、python peek.py で実行します。Windowsなどでは使っている環境に応じて py や python3 を使います。

import dis

def add_one(n):
    return n + 1

print(add_one(2))
dis.dis(add_one)

最初に 3 が表示され、その後にバイトコードの命令一覧が出ます。命令の名前や並びはPythonの版によって変わります。ここで分かるのは「ソースの文字列をそのまま一行ずつ読むだけではない」という点です。この例は速度比較ではありません。

実際に変換と実行を分けて試すならJava入門、ブラウザで操作を動かすならJavaScript入門へ進みましょう。

参考資料