なんでインタプリタ言語って遅いの?

# Overview

突然思い立って、色々調べて見たけど日本語の文献がない。仕方なく英語で調べてみるとstack overflowにいい記事があった。

本当はちゃんと教科書的なので調べた方がいいが、情報を見つけるのが大変なので、簡単にまとめた。

この記事のほとんどが元記事に乗っているので、そちらも参考にしてください。

# Answer1(CPUの観点から)

コンパイル言語はコンパイルされるとそのままマシン語になり、そのマシン語を実行する。一方インタプリンタ言語は実行するたびにインタプリタが解釈し、インタプリタが実行する。

よってCPUの観点に立つと、

# スクリプト言語を利用する時
(CPUの利用率)=(マシン語を利用する分)
# インタプリタ言語を利用する時
(CPUの利用率)=(インタプリタを起動する分)+(インタプリタが実行する分)

こうなるので、コンパイル言語の方が(基本的に)早い。よってインタプリタの起動分のオーバヘッドが速さに影響するということらしい。

因みにインタプリタ言語と言っても、色々な種類があって例えば以下の種類がある。

  1. 完全なインタプリタ言語(PHP, BASIC)
    走らせるたびにインタプリタが起動して、インタプリタを立ち上げながらソースコードを実行していく。
  2. バイトコードを用いるインタプリタ言語(Python)
    まず、ソースコードをバイトコードにコンパイルする。次に仮想マシンを立ち上げて仮想マシンがバイトコードを実行していく。もちろんここで、仮想マシンの立ち上げのオーバヘッドが生じる。
  3. Java系統のインタプリタ言語
    まず、ソースコードをバイトコードにコンパイルする。その後JVMを立ち上げ、Just in time compilationという機能によってバイトコードをマシン語を生成する。最後にマシン語がCPUによって実行される。もちろんここで、JVMの立ち上げのオーバヘッドが生じる。

結論としては、インタプリタ言語は何かを立ち上げる必要があるので、そのオーバヘッドによってコンパイラ言語より遅くなる。

# Answer2(インタプリタの観点から)

例えばアセンブリの ADD 命令を考えてみよう。これをアセンブリで表現すると(私はMIPSしか知らないのでそれで書きます)

ADD $s1, $t1, $t2

のような感じになる。stackの$t1,$t2に格納されている変数の和を$s1に格納することを意味している。

では、あなたが仮にインタプリタを作ることになったとして、 ADD 命令を実装するとする。具体的にはADDという命令が入った場合に、スタックから値を取り出し、それを足し合わせて別のスタックに格納する。

一連の操作をpythonっぽく描いてみると下のようになる。 opecode に命令が格納されているとして変数 stack がstackを表すとする。

if opecode == 'ADD':
op1 = stack.pop()
op2 = stack.pop()
res = op1 + op2
push(&stack, res)

このようにで普通のマシン語に比べてコードが長り、またスタックに対する操作も複雑である。よって、インタプリタ言語はコードが冗長になるのでコンパイラ言語より遅くなる

# Conclusion

元記事でもたくさん議論されていたから、なんとなーく理解できたかなーという感じである。またちゃんとした教科書を読んで勉強しよう

やはりなんとなく感覚で理解していることも、言語化してみると意外と難しい。

# ref

stack overflowのCreative Commons Attribution Share-Alikeに基づき、

## 元記事

## 質問者

## 回答者1(Answer1)

## 回答者2(Answer2)

--

--