web-dev-qa-db-ja.com

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

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

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

9
aris

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

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

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

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

13
Winston Ewert

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

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

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

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

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

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

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

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

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

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

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

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

Pythonは、マシンで簡単に解釈できるように設計されていないためです。人間が簡単に解釈できるように設計されています。 OTOH、CPythonバイトコード、isはマシンで簡単に解釈できるように設計されています。したがって、人間向けに設計された言語のwriteコードと、機械向けに設計された言語のinterpretを使用することは理にかなっており、一方から他方に移動するには、コンパイル。

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

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


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

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

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

インタプリタ、JITコンパイラ、AOTコンパイラの違いの違いとさまざまな手段を説明するこの私の答えこの答えはAOTコンパイラ間の違いを扱っています)およびJITコンパイラ

7
Jörg W Mittag

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

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

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

3
user7043