意外的Cythonized函数

2024-09-28 01:27:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我想加速一个我经常使用的函数,我想用cython。然而,在尝试了我在文档中找到的所有可能的cython优化之后,cython代码大约比python+numpy函数慢6倍。令人失望!在

这是我的测试代码:(forward1是python函数,forward2是cython函数)

#geometry.py
def forward1(points, rotation, translation):
    '''points are in columns'''
    return np.dot(rotation, points - translation[:, np.newaxis])

#geometry.pyx
import numpy as np
cimport numpy as np
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
cdef np.float64_t[:,:] forward2(np.float64_t[:,:] points, np.float64_t[:,:] rotation, np.float64_t[:] translation):
    '''points are in columns'''
    cdef unsigned int I, J
    I = points.shape[0]
    J = points.shape[1]
    cdef np.float64_t[:,:] tmp = np.empty((I, J), dtype=np.float64)
    cdef unsigned int i
    for i in range(J):
        tmp[0, i] = points[0, i] - translation[0]        
        tmp[1, i] = points[1, i] - translation[1]        
    cdef np.float64_t[:,:] result = np.dot(rotation, tmp)
    return result

def test_forward2(points, rotation, translation):
    import timeit
    cdef np.float64_t[:,:] points2 = points
    cdef np.float64_t[:,:] rotation2 = rotation
    cdef np.float64_t[:] translation2 = translation
    t = timeit.Timer(lambda: forward2(points2, rotation2, translation2))
    print min(t.repeat(3, 10))

然后我计时:

^{pr2}$

我能做些什么让cython代码更快些吗?在

如果forward1在cython中不能加速,我能用weave来加速吗?在

编辑:

我想说的是,另一件我试图加快函数速度的事情是按fortran顺序传递点,因为我的点存储在列中,而且其中有很多列。我还将本地tmp定义为fortran顺序。我认为函数的减法部分应该更快,但是纽比.dot似乎需要一个C命令输出(无论如何要解决这个问题?),所以这也没有加速。我还试着转置这些点,这样减法部分在C顺序中更快,但看起来点积仍然是最昂贵的部分。在

我也注意到了纽比.dot不能使用memoryviews作为out参数,即使它是C命令,这是一个bug吗?在


Tags: 函数innumpyfalsenptranslationdottmp
1条回答
网友
1楼 · 发布于 2024-09-28 01:27:13

只要浏览一下您的代码,它看起来像是numpy已经非常适合的东西(数组和点积的减法)。在

Cython非常适合于加速numpy通常执行不佳的情况(例如迭代算法是用python编写的),但是在这种情况下,内部循环已经由BLAS库执行了。在

如果你想加快速度,我首先要看的是BLAS/LAPACK/ATLAS/etc库与numpy的链接。在这种情况下,使用“调优”的线性代数库(如ATLAS或Intel的MKL)会产生很大的不同(在某些情况下,甚至是10倍)。在

要了解您当前使用的是什么,请查看numpy.show_config()的输出

相关问题 更多 >

    热门问题