ネイティブマシンコードへのpythonコンパイラがないのはなぜですか?


25

私が理解しているように、コンパイルされた言語とpythonの速度の違いの原因は、最初のコードがネイティブマシンのコードまですべてコンパイルされるのに対し、pythonはPVMによって解釈されるpythonバイトコードにコンパイルされることです。この方法でPythonコードを複数のオペレーティングシステムで使用できることがわかります(少なくともほとんどの場合)が、理解できない、なぜ従来のコンパイラと同じ方法でコンパイルするPython用の追加の(オプションの)コンパイラがないのかわかりません。これはプログラマーに選択を任せることになり、それは彼らにとってより重要です。ネイティブマシンでのマルチプラットフォームの実行可能性またはパフォーマンス。一般に; コンパイルされたものと解釈されたものの両方として振る舞うことができる言語がないのはなぜですか?


4
があります。GHCiのを通してコンパイルまたは解釈されるHaskellはまた、振る舞うことができる
toasted_flakes

C ++にはインタープリターもあります。そして、おそらく他の多くの言語にも両方の実装があります。
クラウディオ14年

2
実際には、IronPythong(ironpython.net)を選択し、「ngen」(msdn.microsoft.com/de-de/library/6t9t5wcf%28v=vs.110%29.aspx)を使用して生成されたILコードをコンパイルする方法あります。 Pythonをネイティブマシンコードにコンパイルします。そのツールチェーンをテストしたわけではありません。
ドックブラウン14年

10
Pythonからネイティブのコンパイラーを作成できます。Pythonのように見えるがはるかに制限されている言語を実際に実装しない限り、実際にはパフォーマンスを大幅に向上させないため、あまり興味深いものではありません。私は以前に別の場所で説明した理由。

回答:


29

いいえ。PythonとC ++のような言語に速度の違いがある理由は、静的に型付けされた言語がコンパイラにプログラムとそのデータの構造に関する膨大な情報を与え、計算とメモリアクセスの両方を最適化できるためです。C ++は変数がint型であることを認識しているため、プログラムが実行される前であってもその変数を操作する最適な方法を決定できます。一方、Pythonでは、ランタイムは、インタープリターが行に到達するまで変数の値を認識しません。これは構造にとって非常に重要です。C++では、コンパイラはコンパイル中に構造のサイズとメモリ内のそのフィールドのすべての位置を簡単に知ることができます。これにより、データの使用方法を予測する強力な機能が提供され、それらの予測に従って最適化できます。

Pythonのような言語を効果的にコンパイルするには、次のことが必要です。

  1. プログラムの実行中にデータの構造が静的であることを確認してください。Pythonにはevalクラスとメタクラスがあるため、これには問題があります。どちらも、プログラムの入力に基づいてプログラムの構造を変更することを可能にします。これは、Pythonにそのような表現力を与えるものの1つです。
  2. ソースコード自体からすべての変数、構造体、およびクラスの型を推測します。ある程度可能ですが、静的型システムとアルゴリズムは非常に複雑であるため、使用可能な方法で実装することはほとんど不可能です。言語のサブセットに対して行うことはできますが、言語機能のセット全体に対して行うことは絶対にできません。

6
これにより問題が難しくなることは注目に値しますが、不可能ではありません。sbclは Common Lispをコンパイルしますがeval、これも動的であり、を持ち、コンパイラライターを悲しませるために他の多くのものを持っています。gccのレベルではありませんが、CPythonのインタープリターよりも確かに高速です。
ダニエル・グラッツァー14年

3
@jozefg効果的にコンパイルすると言いました。コンパイルするだけではありません。Pythonにもネイティブコードを生成するCythonコンパイラがあります。重要なのは、これらのコンパイラーは、静的に型付けされた言語用のコンパイラーが可能な最適化の一部さえも実行できないことです。また、パフォーマンスを比較するときは、Pythonを解釈せずにコンパイル済みのC ++と比較してください。
陶酔14年

2
実は、sbclで何ができるのか驚くでしょう。ベンチマークゲームは、Javaと同じくらい速く、GHCとほぼ同じくらい速く、Cの1倍から10倍以内で動作していることを示しています。どの標準でも遅くありません。はい、動的型はコンパイルをある程度抑制しますが、あなたが考えているほど多くは抑制しません。
ダニエル・グラッツァー14年

3
解釈されたpythonとコンパイルされたpythonの速度を比較すること自体が興味深いです。「C ++を使用」と言って停止します。たぶん、あなたはすでにPythonで書かれたコードを持っているでしょう。おそらく、Pythonでコードを作成する方が簡単です。誰も気にしない。私が気にしているのは1.5倍のスピードアップです(それが何であれ)。それは大きな違いを生むことができます。
トーマスエディング14年

3
つまり、コンパイルする場合は、C ++やPascalなど、そのために調整された別の言語を選択します。
Please_Dont_Bully_Me_SO_Lords

0

2つの概念は、ネイティブマシンコードにコンパイルされたPythonが、コンパイルされたCまたは他の一般的にコンパイルされた言語ほど速く実行されない理由をよりよく理解するのに役立ちます。それらは、事前バインディングと遅延バインディングと呼ばれます。

私はPythonの専門家ではないと言うことから始めるべきであり、偶然このサイトに来ました。しかし、私はこのサイトが好きです。

ここで別の応答で述べたように、C ++コンパイラはプログラムについて多くのことを知り、特定のデータ構造に使用する操作について決定を下すことができます。たとえば、2つの整数変数を加算する必要がある場合、コンパイラはそれらがネイティブ整数(たとえば32ビット幅)であることを認識し、1つの「ADD」命令でそれらを加算できます。したがって、ADD命令をコードにコンパイルします。ロックされており、プログラムの実行中は変更できません。それは早期バインディングです。

一方、Pythonのような言語では、プログラムがさまざまなタイプのデータを複雑な方法で一緒にスローすることを期待できます。現在、コンパイラは、2つの変数が整数、浮動小数点数、文字列、またはリストであるかどうかを知りません。そのため、実行時にその情報を決定するコードをコンパイルし、プログラムの実行中に正しい操作を選択する必要があります。これは遅延バインディングであり、プログラムの実行中に余分な作業を行うとパフォーマンスが低下することがわかります。Pythonのような言語でこれらのオプションを開いたままにしておくために支払う価格ですが、実行時の柔軟性が最大になります。


-4

Python自体に関係があると思います。これは、C#をマシンコードにコンパイルできない同じ理由です。言語の特性により、たとえ可能であっても、実際にはプログラムはバグが発生します。なぜC言語を学ぶだけではありませんか?C ++よりはるかに簡単で、Pythonよりも少し高度ですが、まだ親しみやすいです。


5
C#は、マシンコードに直接移動できます:Common Intermediate Language:Ahead of Timeコンパイル -「CLI互換の実行環境には、アセンブリのAhead-of-timeコンパイル(AOT)を実行して、削除することでより速く実行するオプションもあります実行時のJITプロセス。.NETFrameworkには、AOTを実行するNative Image Generator(NGEN)と呼ばれる特別なツールがあります。Monoには、AOTを実行するオプションもあります。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.