gpt4 book ai didi

performance - cython 运行速度比 numpy 慢以计算距离

转载 作者:行者123 更新时间:2023-12-01 09:29:46 24 4
gpt4 key购买 nike

我正在努力学习 cython;但是,我一定做错了什么。这段测试代码的运行速度比我的向量化 numpy 版本慢了大约 50 倍。有人可以告诉我为什么我的 cython 比我的 python 慢吗?谢谢。

代码计算 R^3 中的点 loc 和 R^3 中的点数组点之间的距离。

import numpy as np
cimport numpy as np
import cython
cimport cython

DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
@cython.boundscheck(False) # turn of bounds-checking for entire function
@cython.wraparound(False)
@cython.nonecheck(False)
def distMeasureCython(np.ndarray[DTYPE_t, ndim=2] points, np.ndarray[DTYPE_t, ndim=1] loc):
cdef unsigned int i
cdef unsigned int L = points.shape[0]
cdef np.ndarray[DTYPE_t, ndim=1] d = np.zeros(L)
for i in xrange(0,L):
d[i] = np.sqrt((points[i,0] - loc[0])**2 + (points[i,1] - loc[1])**2 + (points[i,2] - loc[2])**2)
return d

这是与它进行比较的 numpy 代码。

from numpy import *
N = 1e6
points = random.uniform(0,1,(N,3))
loc = random.uniform(0,1,(3))

def distMeasureNumpy(points,loc):
d = points - loc
d = sqrt(sum(d*d,axis=1))
return d

numpy/python 版本大约需要 44ms,cython 版本大约需要 2 秒。我在 mac osx 上运行 python 2.7。我正在使用 ipython 的 %timeit 命令对这两个函数进行计时。

最佳答案

np.sqrt 的调用,这是一个 Python 函数调用,正在扼杀你的性能你正在计算标量浮点值的平方根,所以你应该使用 sqrt 来自 C 数学库的函数。这是您的代码的修改版本:

import numpy as np
cimport numpy as np
import cython
cimport cython

from libc.math cimport sqrt

DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
@cython.boundscheck(False) # turn of bounds-checking for entire function
@cython.wraparound(False)
@cython.nonecheck(False)
def distMeasureCython(np.ndarray[DTYPE_t, ndim=2] points,
np.ndarray[DTYPE_t, ndim=1] loc):
cdef unsigned int i
cdef unsigned int L = points.shape[0]
cdef np.ndarray[DTYPE_t, ndim=1] d = np.zeros(L)
for i in xrange(0,L):
d[i] = sqrt((points[i,0] - loc[0])**2 +
(points[i,1] - loc[1])**2 +
(points[i,2] - loc[2])**2)
return d

以下演示了性能改进。您的原始代码在模块 check_speed_original 中,修改后的版本在 check_speed 中:

In [11]: import check_speed_original

In [12]: import check_speed

设置测试数据:

In [13]: N = 10**6

In [14]: points = random.uniform(0,1,(N,3))

In [15]: loc = random.uniform(0,1,(3,))

原始版本在我的电脑上需要 1.26 秒:

In [16]: %timeit check_speed_original.distMeasureCython(points, loc)
1 loops, best of 3: 1.26 s per loop

修改后的版本耗时 4.47 毫秒:

In [17]: %timeit check_speed.distMeasureCython(points, loc)
100 loops, best of 3: 4.47 ms per loop

如果有人担心结果可能会有所不同:

In [18]: d1 = check_speed.distMeasureCython(points, loc)

In [19]: d2 = check_speed_original.distMeasureCython(points, loc)

In [20]: np.all(d1 == d2)
Out[20]: True

关于performance - cython 运行速度比 numpy 慢以计算距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16907215/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com