PyPy —どうすればCPythonに勝てるのでしょうか?


264

Googleのオープンソースのブログ

PyPyは、PythonでPythonを再実装したもので、高度な手法を使用してCPythonよりも優れたパフォーマンスを達成しようとします。長年の懸命な努力がついに報われました。速度の結果は、CPythonに勝る場合が多く、わずかに遅いものから、実際のアプリケーションコードで最大2倍のスピードアップ、小さなベンチマークで最大10倍のスピードアップまでさまざまです。

これはどのようにして可能ですか?PyPyの実装に使用されたPython実装はどれですか?CPython?そして、PyPyPyまたはPyPyPyPyがスコアを打つ可能性は何ですか?

(関連する注意について...なぜ誰もがこのようなことをしようとするのですか?)


43
Nitpick:PyPy PyPyPyです。Py- *接頭辞を射影演算子と考えてください。
u0b34a0f6ae 2010年

OK。PyPyはCPythonよりも優先されるべきですか?それには欠点がありますか?
バルキ

10
PyPyはランタイムの最適化に優れていますが、内部が異なるため、人気のあるいくつかのC拡張と互換性がありません
Cees Timmerman

4
どのようにして速度を上げることが理論的に可能であるかについては、ほとんどの人が問題を見逃しています。しかし、考えてみてください。Pythonは、チューリングマシンと同じように何でもできます。gcc結局、それは呼び出すことができます。したがって、CPythonで実行されるいくつかのpythonコードを記述して、他のいくつかのpythonコードを解釈し、それをCに変換してgcc実行し、コンパイルされたプログラムを実行することもできます。そして、コードが十分に頻繁に呼び出される場合、それはより速くなる可能性があります。
osa

回答:


155

Q1。これはどのようにして可能ですか?

手動のメモリ管理(CPythonがカウントで行う処理)は、自動管理よりも遅くなる場合があります。

CPythonインタープリターの実装の制限により、PyPyが実行できる特定の最適化(たとえば、きめの細かいロック)が妨げられます。

マルセロが言ったように、JIT。オンザフライでオブジェクトのタイプを確認できると、複数のポインター逆参照を行って、最終的に呼び出すメソッドに到達する必要がなくなります。

Q2。PyPyの実装に使用されたPython実装はどれですか?

PyPyインタープリターは、静的に型付けされたPythonのサブセットであるRPythonで実装されています(CPythonインタープリターではなく言語)。-詳細については、https://pypy.readthedocs.org/en/latest/architecture.htmlを参照してください。

Q3。そして、PyPyPyまたはPyPyPyPyがスコアを打つ可能性は何ですか?

それは、これらの架空の通訳の実装に依存します。たとえば、そのうちの1つがソースを取得し、何らかの分析を行い、しばらく実行した後、それをタイトなターゲット固有のアセンブリコードに直接変換した場合、CPythonよりもかなり高速になると思います。

更新:最近、注意深く作成された例で、PyPyはでコンパイルされた同様のCプログラムよりも優れていgcc -O3ます。これは人為的なケースですが、いくつかのアイデアを示しています。

Q4。なぜ誰もがこのようなことをしようとするのでしょうか?

公式サイトより。https://pypy.readthedocs.org/en/latest/architecture.html#mission-statement

私たちは提供することを目指しています:


  • 動的言語の実装を作成するための共通の翻訳およびサポートフレームワーク 。
    言語仕様と実装の
    側面を明確に分離することを強調しています。これをRPython toolchain_ と呼びます。

  • 上記のツールチェーンを使用して、低レベルの詳細をエンコードせずに新しい高度な高レベル機能を有効にする、Python_言語の準拠した柔軟で高速な実装。

このように懸念を分離することにより、Pythonや他の動的言語の実装は、あらゆる動的言語用のジャストインタイムコンパイラーを自動的に生成できます。また、ターゲットプラットフォーム、メモリとスレッドモデル、ガベージコレクション戦略、適用された最適化など、これまでユーザーの制御の外にあったものを含め、実装の決定に対するさまざまなアプローチが可能になります。そもそもJIT。

CコンパイラgccはCで実装されており、HaskellコンパイラGHCはHaskellで書かれています。Pythonインタプリタ/コンパイラがPythonで記述されない理由はありますか?


82
この回答には、PyPyの高速性に関する主な説明が完全に欠落しています。PyPyは実際にはPythonでは実装されていませんが、RPythonでは言及されていますが、RPythonコードが静的にコンパイルおよび最適化されてPyPyインタープリターを生成していることを指摘していません(たまたま、上で実行できる有効なPythonコードでもあります) CPythonの方がはるかに遅い)。「通常のPython」で実装されているのは、RPythonの「コンパイラ」(ブロック引用で言及されている翻訳フレームワーク)です。
ベン

12
これはLedを埋めています。パフォーマンスのほとんどは、Cへの変換(インタープリターがCPythonよりも遅くない)と、ホットパスをはるかに高速にするJITによるものです。
東武

4
「更新:最近、注意深く作成された例で、PyPyはgcc -O3でコンパイルされた同様のCプログラムよりも優れていました。」そして、その投稿の下の最初のコメントを読むと、その投稿の作成者がリンク時の最適化を知らないことがわかります。リンク時の最適化を有効にすると、Cコードの実行が速くなります。
アリ

2
さて、ブログの投稿は2011年で、この回答は2014年でした。また、コメントは共有ライブラリについて言及しています。これ(回答とブログ投稿)のどれだけが有効かわかりません。関連するすべてのテクノロジーは、過去数年間で大きく変化しました。
Noufal Ibrahim 2014

1
慎重に作成された2つのPypyの例は、同等のCよりも高速ですが、非常に具体的な一連の理由により、それぞれがベンチマークで高速です。1つ目は、Pypyがタイトなループカウントを実現するのに十分スマートであるため、そのカウントが使用されることはないため、2つ目を完全に削除(JITパス)できます。 「printf」関数の例は、文字通り整数のみを放出できるように特化されており、繰り返されるmalloc(メモリ割り当てオーバーヘッド)を排除します。
amcgregor

291

「PyPyはPythonでのPythonの再実装です」は、技術的には真実ですが、PyPy、IMHOを説明するのに誤解を招く方法です。

PyPyには2つの主要な部分があります。

  1. 翻訳フレームワーク
  2. 通訳

翻訳フレームワークはコンパイラです。RPythonコードをC(または他のターゲット)にコンパイルし、ガベージコレクションやJITコンパイラなどの側面を自動的に追加します。RPythonのみを処理して、任意のPythonコードを処理することはできません

RPythonは通常のPythonのサブセットです。すべてのRPythonコードはPythonコードですが、その逆はありません。RPythonは基本的に「PyPyの翻訳フレームワークで翻訳できるPythonのサブセット」に過ぎないため、RPythonの正式な定義はありません。しかし、翻訳するには、RPythonコードを静的に型指定する必要があります(型は推測されますが、宣言はしませんが、変数ごとに厳密に1つの型です)。関数の宣言/変更などのことはできません/実行時のクラス。

インタプリタはRPythonで書かれた通常のPythonインタプリタです。

RPythonコードは通常のPythonコードであるため、任意のPythonインタープリターで実行できます。しかし、PyPyの速度に関する主張は、そのように実行したことによるものではありません。インタプリタの翻訳には長い時間がかかるため、これは迅速なテストサイクルのためのものです。

これが理解できれば、PyPyPyまたはPyPyPyPyに関する推測が実際には意味をなさないことはすぐに明らかになります。RPythonで作成されたインタープリターがあります。Pythonをすばやく実行するCコードに変換します。そこでプロセスは停止します。再度処理することでスピードアップするRPythonはもうありません。

したがって、「PyPyがCPythonよりも高速になるのはなぜですか」もかなり明白になります。PyPyは、JITコンパイラを含め、より優れた実装を備えています(JITコンパイラがないと、通常、それほど速くはありません。つまり、PyPyは、JITコンパイルの影響を受けやすいプログラムに対してのみ高速です)。(彼らはそれを非常に作ってみるんがCPythonのは、Python言語の高度最適化実装できるように設計されなかった最適化されたあなたは違いに従うならば、実装)。


PyPyプロジェクトの本当に革新的なビットは、高度なGCスキームやJITコンパイラーを手動で作成しないことです。彼らはインタプリタをRPythonで比較的簡単に記述します。すべてのRPythonはPythonよりも低いレベルであり、オブジェクト指向のガベージコレクション言語であり、Cよりもはるかに高いレベルです。その後、変換フレームワークは自動的に GCやJITなどを追加します。だから翻訳フレームワークは巨大ですPyPy pythonインタープリターにも同じように適用されますが、実装を変更するため、実験の自由度が大幅に向上し、GCバグの導入や、変更に対応するためのJITコンパイラーの更新を心配する必要がありません。また、Python3インタープリターの実装に取り​​掛かると、自動的に同じ利点が得られます。また、PyPyフレームワークで作成された他のインタプリタ(その中には、さまざまな段階のポリッシュがあります)。そして、PyPyフレームワークを使用するすべてのインタープリターは、フレームワークによってサポートされるすべてのプラットフォームを自動的にサポートします。

したがって、PyPyプロジェクトの真の利点は、動的言語用のプラットフォームに依存しない効率的なインタープリターの実装のすべての部分を(可能な限り)分離することです。そして、それらを1か所に実装して、多くのインタープリターで再利用できます。それは「私のPythonプログラムは今より速く実行される」のようにすぐに成功するわけではありませんが、将来の大きな展望です。

そして、それはあなたのPythonプログラムをより速く実行することができます(たぶん)。


4
私は違いを追跡
できませんでした

37
差@polvoazul 最適化された言語の実装と最適化のいずれか?まあ、私がCPythonが十分に最適化された実装であると言うとき、私は開発者がインタープリター自体の内部アルゴリズムと組み込みのデータ構造を効率的に実行しようとすることを意味します。最適化の実装、大藤は、分析しますエンドユーザーのコードを、より効率的に実行するために、それを変換する方法を把握することを試みます。
ベン

23

PyPyはPythonで実装されていますが、JITコンパイラーを実装してネイティブコードをオンザフライで生成します。

Pythonの上にPyPyを実装する理由は、特にJITコンパイラーがホスト言語のパフォーマンスをいくらか無関係にするため、それが単に非常に生産的な言語であるためです。


JITはPyPyと同じレベルで実行されるPythonコードを生成しますか、それともPyPyが実行されているPython実装のレベルで実行される実際のネイティブコードを生成しますか?
エドモンド

3
実際のネイティブコード(ここを参照)正確には32ビットx86コード。
Marcelo Cantos、2010

11

PyPyは制限付きPythonで記述されています。私の知る限り、CPythonインタープリターの上では実行されません。制限付きPythonは、Python言語のサブセットです。AFAIK、PyPyインタープリターはマシンコードにコンパイルされているため、インストール時に実行時にpythonインタープリターを利用しません。

あなたの質問は、コードの実行中にPyPyインタープリターがCPythonの上で実行されていることを期待しているようです。 編集:はい、PyPyを使用するには、最初にPyPy PythonコードをCに変換し、gccでビルドするか、jvmバイトコードに変換するか、.Net CLIコードに変換します。はじめにを参照


8
PyPyはCPythonの上で実行されますが、このモードでは、希望する速度の向上は得られません。:-) codespeak.net/pypy/dist/pypy/doc/...
フランク・V
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.