6

配列に対して数学演算を実行し、結果を返す関数を作成しようとしています。簡単な例は次のとおりです。

def original_func(A):
    return A[1:] + A[:-1]

高速化と、関数呼び出しごとに新しい出力配列の割り当てを回避するために、出力配列を引数として使用し、その場所で変更したいと考えています。

def inplace_func(A, out):
    out[:] = A[1:] + A[:-1]

ただし、これら 2 つの関数を次のように呼び出すと、

A = numpy.random.rand(1000,1000)
out = numpy.empty((999,1000))

C = original_func(A)

inplace_func(A, out)

元の関数は、インプレース関数の2 倍の速さのようです。これはどのように説明できますか?メモリを割り当てる必要がないため、インプレース関数の方が高速であるべきではありませんか?

4

3 に答える 3

12

操作をインプレースで実行する場合は、

def inplace_func(A、アウト):
    np.add(A[1:], A[:-1], アウト)

これは一時的なものを作成しません (これA[1:] + A[:-1]は ) です。

すべての Numpy バ​​イナリ操作には対応する関数があります。ここでリストを確認してください: http://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs

于 2011-09-23T20:28:05.580 に答える
5

答えは次のとおりだと思います。

どちらの場合も を計算A[1:] + A[:-1]し、どちらの場合も実際に中間行列を作成します。

ただし、2 番目のケースでは、新しく割り当てられた大きな配列全体を予約済みメモリに明示的にコピーします。このような配列のコピーには、元の操作とほぼ同じ時間がかかるため、実際には 2 倍の時間がかかります。

要約すると、最初のケースでは、次のようにします。

compute A[1:] + A[:-1] (~10ms)

2 番目のケースでは、

compute A[1:] + A[:-1] (~10ms)
copy the result into out (~10ms)
于 2011-09-23T13:58:09.480 に答える
-1

オリバーの説明に同意します。操作をインプレースで実行する場合は、アレイを手動でループする必要があります。これははるかに遅くなりますが、速度が必要な場合は、純粋な C 実装の速度を提供する Cython に頼ることができます。

于 2011-09-23T15:34:28.643 に答える