コンピュータ用語において、インタプリタとコンパイラは以下のように定義されます。
インタプリタ
ソースコードを読み込み、解釈して実行するもの。
処理の流れ:
コード読み込み → 解釈 → 実行
コンパイラ
ソースコードを読み込み、解釈して別の形式(通常は機械語)に変換するもの。
処理の流れ:
コード読み込み → 解釈 → 変換 → 出力ファイル
インタプリタとコンパイラの分類は、「実行主体の違い」に基づいています。
- インタプリタ: インタプリタが実行を担当します。
- コンパイラ: 出力された実行ファイルが実行を担当します。
インタプリタ | コンパイラ | |
---|---|---|
出力ファイル | なし | あり |
実行 | あり | なし |
誤解1: 「インタプリタは機械語で実行される」
コンピュータは機械語で動くので、コンピュータを動かすには機械語にする必要があるという誤解からきています。
インタプリタは必ずしも機械語に変換して実行するわけではありません。ソースコードをそのまま解釈して実行するインタプリタも存在します。
例: bashシェル
シェルはインタプリタです。
シェルスクリプトを機械語に変換せず、解釈して実行します。
誤解2: 「Javaはコンパイル言語である」
インタプリタの一般的な仕組みを説明します。
以下の流れで処理が進んでいきます。
処理の流れ:
コード読み込み → 構文解釈 → 構文木作成 → 中間コード変換 → インタプリタで実行
Javaの場合:
- 上記の処理の流れの中間コード変換までJavaコンパイラはソースコードを中間コード(バイトコード)に変換し、
.jar
ファイルとして出力します。 - 中間コードの
.jar
ファイルを Javaランタイム(中間コードインタプリタ) が実行します。
インタプリタの処理を中間コード変換部で分離したのがJavaです。
実行はJavaランタイム(インタプリタ)が実行します。
なのでJavaは「インタプリタ言語」に分類されます。
通常のインタプリタ実行時の
コード読み込み → 構文解釈 → 構文木作成 → 中間コード変換
が事前に完了していますので通常のインタプリタよりは
処理速度が速くなります。
さらに、実行時にはバイトコードをJITコンパイルして機械語に変換し実行することもあります。機械語で実行されますので高速に動作します。
しかし、実行の制御はあくまでインタプリタ(Javaランタイム)です。
なのでJITコンパイルしたとしてもjavaはインタプリタ言語です。
誤解3: 「Typescriptはインタプリタ言語である」
TypescriptはTypescriptからJavascriptへのコンパイル言語です。
Typescriptが直接は実行されません。
Typescriptを実行できる処理系(Node.js)もありますが、基本的はコンパイル言語です。
高級言語から機械語への変換ではなく、
高級言語から高級言語の変換なのでコンパイルでなくトランスパイルと言われます。
誤解4: 「Javascriptは実行速度が速い。だからインタプリタは遅くない」
JavascriptインタプリタであるV8エンジンは実行直前に総てを機械語に変換してから実行します。機械語ですので実行速度はコンパイル言語に匹敵します。
V8エンジンでの実行速度が速いのです。インタプリタ方式が速いわけではありません。
誤解5: 「JITコンパイルしているからインタプリタは遅くない」
JITコンパイルすることで機械語に変換されて実行されるので
実行時間はコンパイル言語と同じになります。
しかし、コード読み込み、解釈、中間コード変換の処理時間がかかります。
この時間は0にはならないので、総実行時間を比較するとコンパイル言語よりはトータル時間は遅くなります。
実行速度の比較ではインタプリタ言語はコンパイル言語よりも原理的に遅くなります。
誤解6: 「インタプリタ言語とコンパイル言語の区別は意味がない」
インタプリタ言語とコンパイル言語は実行主体の違いでの分類です。
区別に意味はあります。
JITコンパイルが導入されたことでインタプリタ言語とコンパイル言語の処理系における技術はほぼ同じものが使われます。
現代ではインタプリタとコンパイラの技術的差異はありません。
誤解7: 「インタプリタは一行毎、コンパイラは事前に一括」
というような意味ではありません。
以上 よく間違えられるインタプリタとコンパイラでした。
参考資料