我目前正在尝试优化我用纯Python编写的代码。这段代码非常依赖于NumPy,因为我正在使用NumPy数组。下面是我转换为Cython的最简单的类之一,它只是对两个Numpy数组进行乘法运算。如下:
bendingForces = self.matrixPrefactor * membraneHeight
我的问题是,我是否可以优化这个过程,以及如何优化。当我查看“cython -a”生成的C代码时,发现有很多NumPy调用,这看起来不太高效。
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
我想使用两个for
循环来迭代数组的条目。也许我可以使用编译器通过SIMD操作来优化它?!我尝试过,可以编译,但结果奇怪并且需要很长时间。这是替换函数的代码:
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调用操作?