質問

私は現在、Pure Pythonで書いたコードを最適化しようとしています。このコードは使用します numpy 私はnumpyアレイを使用しているので非常に重く。以下に、私が変換した私のクラスの最も単純なものを見ることができます システン. 。 2つのnumpy配列の乗算のみがあります。ここ:

bendingForces = self.matrixPrefactor * membraneHeight

私の質問は、「Cython -A」の生成には多くのnumpy-Callingsがあり、それはあまり効率的ではないCコードを見ると、これを最適化できるかどうか、どのようにできるかです。

import numpy as np
cimport numpy as np
ctypedef np.float64_t dtype_t
ctypedef np.complex128_t cplxtype_t
ctypedef Py_ssize_t index_t

    cdef class bendingForcesClass( object ):
        cdef dtype_t bendingRigidity
        cdef np.ndarray matrixPrefactor
        cdef np.ndarray bendingForces

        def __init__( self, dtype_t bendingRigidity, np.ndarray[dtype_t, ndim=2] waveNumbersNorm ):
            self.bendingRigidity = bendingRigidity
            self.matrixPrefactor = -self.bendingRigidity * waveNumbersNorm**2

        cpdef np.ndarray calculate( self, np.ndarray membraneHeight ) :
            cdef np.ndarray bendingForces
            bendingForces = self.matrixPrefactor * membraneHeight
            return bendingForces

私が持っていたアイデアは、2つを使用することでした for 配列のエントリをループして反復します。おそらく、コンパイラを使用して、Simd-Operationsでこれを最適化できますか?!コンパイルすることができましたが、奇妙な結果をもたらし、永遠にかかりました。代替機能のコードは次のとおりです。

cpdef np.ndarray calculate( self, np.ndarray membraneHeight ) :

    cdef index_t index1, index2 # corresponds to: cdef Py_ssize_t index1, index2
    for index1 in range( self.matrixSize ):
        for index2 in range( self.matrixSize ):
            self.bendingForces[ index1, index2 ] = self.matrixPrefactor.data[ index1, index2 ] * membraneHeight.data[ index1, index2 ]
    return self.bendingForces

しかし、このコードは、私が言ったように、本当に遅く、予想どおりに機能しません。それで、私は何が間違っているのですか?これを最適化し、numpy呼び出し操作を削除する最良の方法は何ですか?

役に立ちましたか?

解決

単純なマトリックスの乗算の場合、Numpyコードはすでにループを行い、ネイティブに乗算するだけであるため、Cythonでそれを打ち負かすことは困難です。 Cythonは、PythonのループをCithonのループに置き換える状況に最適です。コードがnumpyよりも遅い理由の1つは、配列でインデックスルックアップを行うたびに、

self.bendingForces[ index1, index2 ] = self.matrixPrefactor.data[ index1, index2 ] * membraneHeight.data[ index1, index2 ]

境界チェックなどのより多くの計算を行います(インデックスは有効です)。署名されていないINTにインデックスをキャストすると、デコレーターを使用できます @cython.boundscheck(False) 関数の前。

これを参照してください チュートリアル Cythonコードのスピードアップの詳細については。

他のヒント

おそらく使用してこれをスピードアップできます

for index1 from 0 <= index1 < max1:

範囲を使用する代わりに、私は確信が持てません。

チェックしましたか これはアウトですこれです ?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top