なぜPythonにはコンパイラとインタープリタの両方が必要なのですか?


9

Javaにはコンパイラーとインタープリターの両方が必要であるという事実を理解できます。ソースコードをバイトコードにコンパイルしてから、仮想マシン(Windows、Linux、Androidなど)がそのバイトコードを現在のアーキテクチャのマシンコードに変換します。

しかし、なぜPythonにはコンパイラとインタープリタの両方が必要なのでしょうか。Pythonはプラットフォームに依存しないため、解釈を使用しないのはなぜですか?私の知る限り、Pythonプログラム(バイトコードにコンパイルされたもの)を変更せずにWindowsまたはLinuxマシンで実行することはできません。それとも私は間違っていますか?


あなたは間違っている可能性があります。Pythonの代わりにLuaを使用している場合は、誤りです。
Basile Starynkevitch、2015

回答:


13

私の知る限り、WindowsやLinuxなど、すべてのマシンでPythonプログラム(バイトコードにコンパイルされた)を変更せずに実行することはできません。

あなたは間違っています。Pythonバイトコードはクロスプラットフォームです。参照は、Pythonのバイトコードのバージョンに依存しますか?プラットフォームに依存していますか?スタックオーバーフロー。ただし、バージョン間で互換性はありません。Python 2.6はPython 2.5ファイルを実行できません。そのため、クロスプラットフォームですが、一般に配布形式としては役立ちません。

しかし、なぜPythonにはコンパイラとインタープリタの両方が必要なのでしょうか。

速度。厳密な解釈は遅いです。事実上すべての「解釈された」言語は、実際にソースコードを何らかの内部表現にコンパイルするため、コードを繰り返し解析する必要はありません。Pythonの場合は、この内部表現をディスクに保存して、次にコードが必要になったときに解析/コンパイルプロセスをスキップできるようにします。


7

Javaにはコンパイラーとインタープリターの両方が必要であるという事実を理解できます。

そうではありません。Java言語仕様には、Javaにはコンパイラーが必要であると述べられていません。また、Java言語仕様には、Javaにインタープリターが必要であると書かれていません。

インタープリターを使用するか、コンパイラーを使用するか、またはこの2つの組み合わせを使用するかは、完全に実装者の裁量に任されています。

実際には、そこにあるマシンコードに直接コンパイルしたJavaの実装では、JavaのためのGNUコンパイラは、例えば、gcj。技術的に言えば、Oracle OpenJDK Javaコンパイラは、マシンコード、具体的にはJVMバイトコードにもコンパイルされます。今、あなたは言うかもしれません、ちょっと待ってください、それはマシンコードではありません!しかし、x86マシンコード用のソフトウェアインタープリターがあり、JVMバイトコードを実行できるハードウェアCPUがあるので、一方が「ネイティブ」になり、もう一方が「ネイティブ」にならないのはなぜですか。

JVMバイトコードは、x86マシンコードと同じように、Java言語仕様の外側にあることに注意してください。

次に、仮想マシン(Windows、Linux、Androidなど)がそのバイトコードを現在のアーキテクチャのマシンコードに変換します。

繰り返しますが、それは完全に実装者次第です。

元のSun JVMは変換されず、常に解釈されました。現在のOracle OpenJDK JVMは解釈し、頻繁に実行される部分のみがコンパイルされます。Maxine Research VMは常にJITコンパイルを行います。Excelsior.JET実装は、事前に1回コンパイルされます。IKVM.NET JVMはCILバイトコードにコンパイルされます。Androidランタイムは、インストール時に事前に1回コンパイルされます。(また、AndroidランタイムはJVMバイトコードを認識せず、完全に異なる言語であるDalvikバイトコードを使用します。)

しかし、なぜPythonにはコンパイラとインタープリタの両方が必要なのでしょうか。

繰り返しますが、そうではありません。Python言語仕様には、Pythonにはコンパイラーが必要であると書かれていません。また、Python言語仕様には、Pythonにインタープリターを用意する必要があると述べているものはありません。

実際には、Pythonが解釈されることはありません既存のすべて Python実装は、常に Pythonを別の言語にコンパイルします。その言語は次に解釈される場合とされない場合がありますが、その言語はPythonとは異なる言語です。Pythonは解釈されません。

なぜ単に解釈を使用しないのですか?

Pythonはマシンが簡単に解釈できるように設計されていないからです。人間が簡単に解釈できるように設計されています。大藤、CPythonのバイトコードは、されやすいマシンによって解釈されるように設計されています。したがって、人間向けに設計された言語でコードを記述し、マシン向けに設計された言語で解釈することは理にかなっており、一方から他方に進むには、コンパイルする必要があります。

私の知る限り、Pythonプログラム(バイトコードにコンパイルされたもの)を変更せずにWindowsまたはLinuxマシンで実行することはできません。

はい、できます。CPython VMは、PyPy、Jython、IronPythonと同様に、WindowsとLinuxの両方で使用できます。


言語をコンパイルまたは解釈する必要はありません。言語はただです。実際、インタープリターやコンパイラーがなくて、言語は完全に存在できます。たとえば、1930年代に彼が設計したKonrad ZuseのPlankalkülは、生涯にわたって実装されたことはありません。それでも、プログラムを記述したり、それらのプログラムを分析したり、それらについて推論したり、それらのプロパティを証明したりできます。実行することはできません。(まあ、実際、それは間違っています。もちろん、頭の中で、またはペンと紙でそれらを実行できます。)

現在、言語の特定の実装では、コンパイラー(または複数のコンパイラー)、インタープリター、または任意の組み合わせを使用できます。しかし、それは言語ではなく、実装の特性です。すべての言語はコンパイラで実装でき、すべての言語はインタプリタで実装できます。

ただし、インタープリターなしではプログラムを実行できないことに注意してください。コンパイラは単にプログラムをある言語から別の言語に変換します。しかし、それだけです。これで、同じプログラムが別の言語で提供されました。唯一、実際にプログラムの結果を取得する方法はあるし、解釈を。時々、言語は非常に単純なバイナリマシン言語であり、インタプリタは実際にはシリコーンでハードコードされています(これを「CPU」と呼びます)が、それはまだ解釈です。

また、インタプリタ、JITコンパイラ、AOTコンパイラの違いや異なる手段を説明するこの私の答えと、AOTコンパイラJITコンパイラの違いを扱うこの答えに興味があるかもしれません。


3
質問に答えるのではなく、ほとんどの時間を独断的に過ごす答えは私を悲しくさせます。
Winston Ewert 2015

3

バイトコードが配布形式として適切でないことは事実ですが、それが役に立たないという意味ではありません。特定のマシンの起動時間を改善することを除いて、最初の実行後、バイトコードの解釈は、ASTの解釈や、行ごとの解釈よりもはるかに簡単です。

バイトコードは、コードのより低レベルで、より規則的で、よりコンパクトな(意味的にもメモリレイアウトの観点からも)表現です。操作の順序は既に詳しく説明されており、ローカル変数名はより単純な形式(整数のインデックス)に解決されています。複雑な構文に従う必要はなく、単純な命令を次々に実行します。さらに、必要な状態は少なくなります。行ごとの解釈では、基本的にパーサー全体を保持する必要があり、ASTインタープリターはツリートラバーサルでコールスタックを爆破しますが、バイトコードインタープリターは一時的な値に小さなスタックを必要とするだけです。と地元の人。

これらの要因および他の要因により、バイトコードインタープリターは他のインタープリターよりも大幅に高速化されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.