web-dev-qa-db-ja.com

PythonはそのコードをCでどのようにコンパイルしますか?

Pythonのいくつかの構成はCでコンパイルされるため、より効率的であると私は読んだ。

https://wiki.python.org/moin/PythonSpeed/PerformanceTips

使用された例のいくつかはmap()とfilter()でした。 Pythonはこれをどのように行うことができますか?それは一般的に解釈されます。それで、一部のコードは別のコードが解釈されている間にどのようにコンパイルされますか?そして別の言語で?なぜ全体をコンパイルしないのですか?事?

7
Howcan

Pythonのいくつかの構成はCでコンパイルされるため、より効率的であると私は読んだ。

それは真実ではない。

まず、Python言語の仕様には、特定の関数を特定の言語で実装する必要があることを要求するものはありません。APython関数と言語構造を実装するには、彼が望む方法を使用します。たとえば、Jythonでは、これらの関数はCではなくJavaで実装されます。IronPythonでは、C#で実装されます。PyPyでは、RPythonまたはPythonだけで実装される場合があります。 。Pynieでは、おそらくPythonで実装されます。

ひたすら、C言語の仕様にはコンパイルしなければならないという記述はありません。 Cには通訳がいます。

第三に、それがCにあるからといって、それが速いということではありません。本当にひどいコードを生成するCコンパイラが世の中にあり、かなり高速なPython実装があります。

そして第4に、Cで実装された関数が非常に高速であっても、プログラム全体の実行速度が速くなるとは限りません。通常、最適化は言語間で機能しません。たとえば、プログラムはmapの呼び出しをプログラムにインライン化できません。これは、プログラムがPythonで記述されていますが、mapはCで記述されているためです。ただし、インライン化(​​およびループのアンロール)により、ブランチや呼び出しのないコードのニースの長い直線パスが得られるため、インライン化はすべての最適化の基本です。これは、オプティマイザloveです。

一般的に解釈されます

実際、all現在存在しますPython実装は常にコンパイルPythonコード、彼らはそれを決して解釈しません。

なぜ全部をコンパイルしないのですか?

それは良い質問です!すべてを同じ言語で書くことには多くの利点があり、そのうちのいくつかを上記で概説しました。 (もう1つは、2つの言語よりも1つの言語を知っている協力者を見つける方が簡単なことです。)

すべてが同じ言語で記述されている場合、その言語のパフォーマンスの向上はシステム全体で増大します。すべてがCで記述されている場合、Python 10倍高速にしても、ほとんどのコードはPythonではないため、プログラムの速度はそれほど向上しません。確かに、コード- あなたが書いたは10倍速く実行されていますが、そのコードはほとんどが以前と同じ速度のC関数の呼び出しで構成されています。

しかし、すべてがPythonで記述されている場合、Python=より速くすることは波及効果をもたらします:プリミティブ型がより速くなり、それらのプリミティブ型の上に構築されたデータ構造がより速くなり、それらのデータ構造を使用するアルゴリズムより速くなると、これらのアルゴリズムを使用するモジュールはより速くなります。

6
Jörg W Mittag

インタープリター自体はCで書かれています(または少なくともCPythonのリファレンス実装です)。つまり、すべての言語機能が小さなC関数で実装されています。インタープリターが行うのは、ソースコードを読み取って、これらの小さな関数のどれを呼び出すかを見つけることだけです。

これは、より複雑な関数をC実装に委任することも問題ではないことを意味します。

これらの関数はプログラムでコンパイルされません。これらは、コンパイル済みの形式でPythonインタプリタに既に存在し、ソースコードで遭遇したときに呼び出されます。

11
Philipp

それらが「Cでコンパイルされている」と言うことは、少し混乱するような発言です。言い換えましょう。CPython(Pythonインタープリターの最も普及している実装)はCプログラムであり、これらはインタープリターに組み込まれたC関数であり、Pythonコードではありません。インタプリタは魔法のようにCへのコンパイルを選択します。

.pyファイルをPythonにフィードすると、ファイルが解析され、各関数がバイトコードに変換されます。つまり、関数が実行する操作のコンパクトなバイナリ形式になります。これはPython仮想マシンに供給されます。仮想マシンは、バイトコードを読み取り、指示どおりに実行するインタプリタの一部です。

Pythonで記述された関数を呼び出す場合、特別なことは何も起こりません。VMは、ジャンプしてバイトコードを解釈します。しかし、インタープリター内に組み込まれている関数を呼び出すと、インタープリターは組み込みの対応するC関数を呼び出します(これは常に発生します。たとえば、プリミティブ型に対するほとんどの操作は、インタープリター内で直接コンパイルされたコードによって実際に実行されます) )。

CPythonでCで記述された関数は、パフォーマンスが高く、ネイティブコードにコンパイルされた(インタープリターは不要で、CPUで直接実行される)言語で記述されているため、一般的に高速です。たとえば、Pythonでは、メンバーへの各アクセスは複雑なハッシュテーブルルックアップです。Cでは、1つのアセンブリ命令に要約できます)。

それは一般的に解釈されるので、別の言語が解釈されている間に、別の言語で、コードの一部はどのようにコンパイルされますか?なぜ全部をコンパイルしないのですか?

コンパイルするコードと解釈するコードを決定するのはインタープリターだとお考えでしょう。それは間違った前提です。コンパイルされた部分はCPython開発者によってCで直接記述されているのコードであり、インタープリターが構築されるとインタープリター内でコンパイルされます(Cまたは他のコンパイル済み言語で記述された他のコードはPython Python拡張機能でコンパイルされている場合、またはctypesを介してコンパイルされている場合)。 runを実行すると、すべてのCPythonインタープリターが実行できます。Pythonを解釈して、既成のC関数を呼び出すだけです。

4
Matteo Italia

それ自体は「Cでコンパイル」されていません。mapfilterは、言語実装(この場合はCPython)によって提供される標準ライブラリの組み込み関数です。 CPythonはCで記述されているため、必要に応じて、Cで任意のプリミティブ関数を簡単に実装できます。

3
Rufflewind