2011-12-05 34 views
25

私はプログラムを変更しました。性能に関する問題を抱えていたので、データを数値配列として保持するように書いています。その違いは信じられませんでした。もともとは実行に30分かかっていましたが、今は2.5秒かかります!なぜNumPyアレイは高速ですか?

私はそれがどうしているのだろうと思っていました。私はそれがforループの必要性を取り除くが、それを超えて私は困惑していると思う。

+4

numpy配列はPythonではなくC言語で実装されているため、私はそれを推測しています。 –

+7

@NoufalIbrahim:Pythonリストも[Cで実装されています](http://stackoverflow.com/questions/3917574/how-is-pythons-list-implemented/3958322#3958322)。 –

+7

2つの異なるプログラムが何をしていたか、どのように実装されているかについての兆候なしに、かなり曖昧な質問。 –

答えて

52

ナンシーアレイは、均質タイプの密にパックされたアレイです。対照的に、Pythonリストは、たとえすべてが同じ型であっても、オブジェクトへのポインタの配列です。したがって、locality of referenceのメリットが得られます。

また、多くのNumpy演算がCで実装されているため、Pythonでのループの一般的なコスト、ポインタの間接指定、および要素ごとの動的型チェックを避けることができます。スピードブーストは、実行している操作によって異なりますが、数値処理プログラムでは桁外れです。

+1

これらのCで書かれた操作のためにPythonフロントエンドを提供するにはどうすればいいですか?この技術とは何ですか? –

+0

これは当てはまりません。要素が整数などのプリミティブ型の場合、Pythonリストはポインタの配列ではありません。簡単にテストするには、変数に数値を保存し、その変数を含む配列を作成します。変数を変更すると、配列は変更されません。 – Rohan

+0

@Rohanプリミティブ型もオブジェクトであることを覚えておいてください。その変数をリストに追加すると、実際には特定の変数が指すオブジェクトをリストに追加するだけです。この場合、このオブジェクトは数値です。したがって、変数を変更したり、より正確には名前を新しい整数にリバインドすると、元のオブジェクトのプロパティ、つまり元の番号は変更されません。したがって、配列の '対応する'数値はその値を変更しないことが期待されます。 – Kun

1

ナンシーアレイは、cのような「通常の」アレイと極端に似ています。すべての要素は同じ型でなければならないことに注意してください。プリフェッチを利用することができ、配列の要素に索引で即座にアクセスできるため、スピードアップが優れています。

+0

要素ごとに同じタイプを使用すると計算が高速になる方法について詳しく説明できますか? – Rohan

9

numpy配列は特殊なデータ構造です。 これは、効率的なメモリ内表現の利点を得るだけでなく、効率的な特殊化された実装も得られることを意味します。

など。 2つの配列を合計すると、ループ内でのintの追加をpythonで実装するのではなく、特殊なCPUベクトル演算で追加が実行されます。

+1

これらの(特殊な操作と動的最適化)は正しい答えです。プリペッチや参照のローカリティなどのマイナーファクタは、主なパフォーマンス要因(インタープリタオーバーヘッド)が処理された後にのみ重要になります。 – Dave

+2

参照のローカリティは、ローカリティ自体(およびキャッシュへの影響)と、間接指定の欠如が間接参照を処理するための命令をスキップできるという2つの理由から重要です。 –

1

forループはまだありますが、cで実行されます。 Numpyは、線形代数演算のライブラリであるAtlasに基づいています。

http://math-atlas.sourceforge.net/

大きな計算に直面したとき、それはこの時点で私たちのコンピュータ上で最速の一つである見つけるためにいくつかの実装を使用してテストを実行します。いくつかのnumpyビルドでは、複数のCPU上でコミットを並列化することができます。したがって、連続したメモリブロック上で実行されるcの高度な最適化が可能になります。

+5

NumpyはAtlasをベースにしていません。可能であれば、機能の非常に小さなサブセット(基本的にドット、gemv、gemm)に対してBLASの実装を使用することができます。そのBLASは、付属の組み込みリファレンスBLAS、またはAtlas、またはIntel MKL(これに伴って組み込まれたディストリビューションに組み込まれています)でもかまいません。 – talonmies

関連する問題