web-dev-qa-db-ja.com

PythonプログラムがCまたはC ++で記述された同等のプログラムよりも遅いことが多いのはなぜですか?

Python平均して、C/C++より遅いように見えるのはなぜですか?私は最初のプログラミング言語としてPythonを学びましたが、Cで始めたばかりですすでに私は明確な違いを見ることができると感じています。

58
Riemannliness

PythonはCよりも高いレベルの言語です。つまり、メモリ管理やポインタなど、コンピュータの詳細を抽象化し、人間の考え方に近い方法でプログラムを記述できます。

実行時間のみを測定する場合、Cコードは通常Pythonコードよりも10〜100倍速く実行されることは事実です。ただし、開発時間も含めると、PythonはCを上回ることがよくあります。多くのプロジェクトでは、開発時間はランタイムパフォーマンスよりもはるかに重要です。開発時間が長くなると、直接追加コスト、機能が少なくなり、市場投入までの時間が長くなります。

Pythonコードの実行速度が内部的に低下するのは、コードがコンパイル時にネイティブコードにコンパイルされるのではなく、実行時に解釈されるためです。

Javaバイトコードや.NETバイトコードなどの他のインタープリター言語は、標準ディストリビューションに JITコンパイラー が含まれているため、Pythonよりも高速に実行されます。実行時にバイトコードをネイティブコードにコンパイルします。 CPythonにJITコンパイラーがまだない理由は、Pythonの動的な性質により、JITコンパイラーを作成することが困難だからです。 progress には work があり、より高速に記述できますPythonしたがって、将来的にパフォーマンスのギャップが減少することを期待する必要がありますが、標準のPythonディストリビューションに強力なJITコンパイラが含まれるようになるまでにはしばらく時間がかかるでしょう。

69
Mark Byers

ジャストインタイムオプティマイザーがないため、CPythonは特に低速です(これはリファレンス実装であり、場合によってはパフォーマンスよりもシンプルさを選択するため)。 nladen Swallow は、LLVMを利用したJITをCPythonに追加するプロジェクトであり、大幅な高速化を実現します。 JythonとIronPythonは、CPythonよりもはるかに高速で、高度に最適化された仮想マシン(JVMおよび.NET CLR)に支えられている可能性があります。

間違いなくPythonが遅くなる理由の1つは、動的に型指定されることと、各属性アクセスに対して大量のルックアップがあることです。

たとえば、オブジェクトfAで呼び出すと、___dict___でルックアップが実行され、___getattr___が呼び出されます。最後に、呼び出し可能オブジェクトで___call___が呼び出されます。オブジェクトf

動的型付けに関しては、処理するデータのタイプがわかっている場合に実行できる多くの最適化があります。たとえば、JavaまたはCでは、合計したい整数の直線配列がある場合、最終的なアセンブリコードは、インデックスiで値をフェッチするのと同じくらい簡単です。 、それをaccumulatorに追加し、次にiをインクリメントします。

Pythonでは、これをコードを最適化することは非常に困難です。 intsを含むリストサブクラスオブジェクトがあるとします。追加する前に、Pythonはlist.__getitem__(i)を呼び出す必要があります。次にaccumulator.__add__(n)を呼び出してそれを「アキュムレータ」に追加し、繰り返します。代替ルックアップのトンaddまたはgetitemの呼び出しの間に別のスレッドが___getitem___メソッド、リストインスタンスのdict、またはクラスのdictなどを変更した可能性があるため、ここで発生する可能性があります。アキュムレータとリスト(および変数ローカル名前空間でdictルックアップが発生します。ユーザー定義オブジェクトを使用する場合、これと同じオーバーヘッドが適用されますが、一部の組み込みタイプでは多少軽減されます。

また、bigint(int in Python 3、long in Python 2.x)、list、set、dict、などは、Pythonでよく使用されるものです。これらのオブジェクトには、十分に最適化された組み込みの操作が数多くあります。たとえば、上記の例では、代わりにsum(list)を呼び出すだけです。アキュムレータとインデックスを使用する方法です。これらに固執し、int/float/complexを使用して数値を計算すると、一般に速度の問題は発生しません。そうした場合、おそらく時間にクリティカルな小さな単位(SHA2ダイジェスト関数)があります。たとえば、)C(またはJavaコード、Jythonの場合)に簡単に移動できます。実際、CまたはC++をコーディングすると、無駄になりますlotsPythonコードの数秒/行で実行できることを実行する時間。トレードオフは組み込みプログラミングやリアルタイムプログラミングのようなことをしていて、それを買う余裕がない場合を除いて、常に価値があります。

ここではコンパイルと解釈の違いは重要ではありません。Python isコンパイル済みであり、重要なプログラムの実行コストのごく一部です。

主なコストは次のとおりです。ネイティブ整数に対応する整数型の欠如(すべての整数演算を非常に高価にする)、静的型付けの欠如(メソッドの解決をより困難にし、値の型をチェックする必要があることを意味します)実行時)、およびボックス化されていない値の欠如(メモリ使用量を削減し、一定レベルの間接参照を回避できます)。

これらのことのいずれも不可能であるか、Pythonでより効率的にすることができないというわけではありませんが、ランタイム速度よりもプログラマーの利便性と柔軟性、および言語のクリーンさを優先するように選択されています。これらのコストの一部は、巧妙なJITコンパイルによって克服される可能性がありますが、Pythonが提供する利点は、常に何らかのコストでもたらされます。

12
user97370

pythonとCの違いは、解釈済み(バイトコード)言語とコンパイル済み(ネイティブ)言語の通常の違いです。個人的には、python =遅いので問題なく管理できます。レルムの外で使用しようとすると、もちろん遅くなります。ただし、そのために、ネイティブコードにタイムクリティカルなアルゴリズムを配置するpythonのC拡張機能を記述できます。高速化します。

9
Femaref

Pythonは通常、スクリプト言語として実装されます。つまり、最初から機械語で実行可能ファイルを用意するのではなく、コードをその場で機械語に変換するインタープリターを通過します。その結果、コードを実行するだけでなく、コードを変換するコストを支払う必要があります。これは、機械語に近いバイトコードにコンパイルされるため、CPythonにも当てはまります。したがって、より速く翻訳できます。 Pythonを使用すると、動的タイピングなどの非常に便利なランタイム機能も利用できますが、そのようなものは通常、重いランタイムコストなしで最も効率的な実装であっても実装できません。

シェーダーの作成など、プロセッサーを集中的に使用する作業を行っている場合、PythonがC++の約200倍遅いことは珍しくありません。CPythonを使用すると、その時間は半分に短縮されますが、それでもまだそれほど速くはありません。これらすべてのランティミーグッズには価格があります。これを示すベンチマークはたくさんあります here's 特に良いものです。フロントページで認められているように、ベンチマークには欠陥があります。それらはすべて、選択した言語で効率的なコードを書くために最善を尽くしているユーザーによって提出されますが、それはあなたに良い一般的なアイデアを与えます。

効率が気になる場合は、この2つを組み合わせてみることをお勧めします。そうすれば、両方の利点を最大限に引き出すことができます。私は主にC++プログラマーですが、多くの人々がC++で平凡な高レベルのコードをコーディングしすぎるのは、それが面倒な場合(コンパイル時間は1つの例にすぎません)にすぎません。スクリプト言語をC/C++のような金属に近い効率的な言語と混合することは、プログラマーの効率(生産性)と処理効率のバランスを取るための実際の方法です。

4
stinky472

すでに投稿されている回答のほかに、1つは実行時にPythonで変更できる機能で、たとえばCでは変更できません。メンバー関数をクラスに追加することもできます。また、pythonの動的な性質により、関数に渡されるパラメーターのタイプを指定することができなくなり、最適化が非常に困難になります。

RPython は、最適化の問題を回避する方法のようです。

それでも、数値計算などのCのパフォーマンスに近いとは言えません。

3
Mattias Nilsson

C/C++とPythonの比較は公平な比較ではありません。 F1レースカーとユーティリティトラックを比較するようなものです。

驚くべきことは、他の動的言語の同類と比較してPythonの速度が速いことです。方法論はしばしば欠陥があると考えられていますが、 コンピューター言語ベンチマークゲーム を見て、同様のアルゴリズムでの相対的な言語速度を確認してください。

Perl、Ruby、C#との比較はより「公平」です

3
dawg

CおよびC++はネイティブコードにコンパイルされます。つまり、これらはCPUで直接実行されます。 Pythonはインタープリター型言語です。つまり、記述したPythonコードは、実行可能なマシンコードになる前に、多くの抽象化段階を経る必要があります。

1
Puppy