Python / Numpy配列操作のパフォーマンスは、配列の次元の増加に伴ってどのようにスケーリングしますか?


21

Python / Numpy配列は配列の次元の増加に伴ってどのようにスケーリングしますか?

これは、この質問に対するPythonコードのベンチマークテスト中に気づいたいくつかの動作に基づいています:numpyスライスを使用してこの複雑な式を表現する方法

この問題のほとんどは、配列を作成するためのインデックス付けに関係していました。Pythonループ上で(あまり良くない)CythonとNumpyバージョンを使用する利点は、関係する配列のサイズによって異なることがわかりました。NumpyとCythonの両方は、ある時点まで(Cythonの場合は、Numpyの場合はN = 2000程度)のパフォーマンス上の利点が増加し、その後利点は低下しました(Cython機能は最速のままでした)。N=500N=2000

このハードウェアは定義されていますか?大規模な配列で作業するという点で、パフォーマンスが高く評価されているコードについて従うべきベストプラクティスは何ですか?

ベクトル化およびCython実装のループコードに対する実行時間のプロット

この質問(なぜMatrix-Vector Multiplication Scalingではないのですか?)は関連している可能性がありますが、Pythonで配列を処理するさまざまな方法が相互にどのようにスケーリングするかについてもっと知りたいと思っています。


numexprを試しましたか?たとえば、bloscCArrayを指すこの講演もありますが、これらはすべて物事をさらに高速化することを意図しています(そして、メモリ帯域幅の制限を回避する可能性があります)。
0 0

1
プロファイルに使用されるコードを投稿できますか。おそらくここでいくつかのことが起こっています。
meawoppl

回答:


5

416kB

def timeit(size):
     t0 = time.time()
     for _ in xrange(10):
         np.random.random(size)
     return time.time() - t0

sizes = np.logspace(1, 6, 40)
times = [timeit(s) for s in sizes]

このベンチマークにはいくつかの問題があります。最初は、ガベージコレクションを無効にせず、合計を取得しています。最適な時間ではありませんが、私は耐えてください。

800064kB

キャッシュサイズを心配する必要がありますか?原則として、ノーと言います。Pythonで最適化するということは、疑わしいパフォーマンス向上のために、コードをより複雑にすることを意味します。Pythonオブジェクトは、追跡や予測が困難なオーバーヘッドをいくつか追加することを忘れないでください。これが関連する要因である2つのケースしか考えられません。

  • メモリ帯域幅によって制限される、大きな配列の基本操作(多項式の評価など)。使用Numexprまたは(データははるかに大きい場合)Pytables。これらは、他の最適化の中でキャッシュサイズを考慮して最適化されています。
  • パフォーマンスが重要なコード:マイクロ秒ごとに圧縮したい場合は、そもそもPythonを使用しないでください。ベクトル化されたCythonを作成し、コンパイラーにそれが最善を尽くすようにするのは、おそらく苦痛のない方法です。

コメントでは、EvertはCArrayについて言及しました。動作していても、開発は停止しており、スタンドアロンプ​​ロジェクトとして放棄されていることに注意してください。その機能は、「新世代のNumpy」を作成する進行中のプロジェクトであるBlazeに含まれます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.