最終更新:
コンパイラとインタプリタの違い — 「変換する」と「実行する」を図解
「変換」と「実行」は組み合わせられる
コードを書いたのに、そのままCPUが読めるわけじゃないんだよね?
コンパイラは、本をまとめて翻訳する感じ?
別の形式へ翻訳するという意味では似ているよ。ただし出力は機械語だけとは限らない。Cなどから機械語へ進む例も、JavaのソースからJVM向けのクラスファイルへ変換する例もあるんだ。
インタプリタは一行ずつ訳すの?
言語のルールと、その実装の動かし方は分けると正確だよ。同じ言語にも異なる実装がある。JavaScriptのV8では、バイトコードを扱うインタプリタと、実行中に機械語を生成するコンパイラを組み合わせているよ。
実行中にコンパイルするのがJITなんだね?
コンパイルするほうが、いつも速いの?
それだけでは決められないよ。変換や起動にかかる時間、繰り返す処理、外部ライブラリ、I/Oなどで違う。長く動く処理の速さと、起動してすぐの応答も別だから、実際の用途に合った測定が必要だね。
エラーが見つかるタイミングも違う?
最初は何を覚えればいいかな?
「変換」と「実行」を別の仕事として見る
図のファイルは変換でできるもの、矢印はその変換、実行環境は命令を動かすものです。コンパイラとインタプリタは、言語の人気や優劣の名前ではありません。
| 例 | 変換・実行の見方 |
|---|---|
| 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入門へ進みましょう。