なんでインタプリタ言語って遅いの?
# Overview
突然思い立って、色々調べて見たけど日本語の文献がない。仕方なく英語で調べてみるとstack overflowにいい記事があった。
本当はちゃんと教科書的なので調べた方がいいが、情報を見つけるのが大変なので、簡単にまとめた。
この記事のほとんどが元記事に乗っているので、そちらも参考にしてください。
# Answer1(CPUの観点から)
コンパイル言語はコンパイルされるとそのままマシン語になり、そのマシン語を実行する。一方インタプリンタ言語は実行するたびにインタプリタが解釈し、インタプリタが実行する。
よってCPUの観点に立つと、
# スクリプト言語を利用する時
(CPUの利用率)=(マシン語を利用する分)# インタプリタ言語を利用する時
(CPUの利用率)=(インタプリタを起動する分)+(インタプリタが実行する分)
こうなるので、コンパイル言語の方が(基本的に)早い。よってインタプリタの起動分のオーバヘッドが速さに影響するということらしい。
因みにインタプリタ言語と言っても、色々な種類があって例えば以下の種類がある。
- 完全なインタプリタ言語(PHP, BASIC)
走らせるたびにインタプリタが起動して、インタプリタを立ち上げながらソースコードを実行していく。 - バイトコードを用いるインタプリタ言語(Python)
まず、ソースコードをバイトコードにコンパイルする。次に仮想マシンを立ち上げて仮想マシンがバイトコードを実行していく。もちろんここで、仮想マシンの立ち上げのオーバヘッドが生じる。 - 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に基づき、
## 元記事
- 「Why is an interpreter slower than a compiler in practice? — Stack Overflow」https://stackoverflow.com/questions/7991877/why-is-an-interpreter-slower-than-a-compiler-in-practice
## 質問者
- name: algorithmicCoder
- profile: https://stackoverflow.com/users/648927/algorithmiccoder
## 回答者1(Answer1)
- name: Gustav Bertram
- profile: https://stackoverflow.com/users/1005039/gustav-bertram
## 回答者2(Answer2)
- name: chill
- profile: https://stackoverflow.com/users/390807/chill