提高Cython数组索引速度
我有一个比较简单的函数,需要让它运行得更快。基本上,我有一个包含16位数字的大数组,但里面有一些空缺(大约10%)。我需要遍历这个数组,找到连续两个0的地方,然后用前一个和后一个元素的平均值来填补这些0。在C语言中,这个过程只需要几毫秒,但在Python中就慢得多。
我把普通的Python数组换成了numpy数组,然后用cython编译了我的代码,但离我想要的速度还有很大差距。我希望有经验的人能看看我在做什么,并给我一些反馈。
我的普通Python代码是这样的:
self.rawData = numpy.fromfile(ql, numpy.uint16, 50000)
[snip]
def fixZeroes(self):
for x in range(2,len(self.rawData)):
if self.rawData[x] == 0 and self.rawData[x-1] == 0:
self.rawData[x] = (self.rawData[x-2] + self.rawData[x+2]) / 2
self.rawData[x-1] = (self.rawData[x-3] + self.rawData[x+1]) /2
我的Cython代码看起来很相似:
import numpy as np
cimport numpy as np
DTYPE = np.uint16
ctypedef np.uint16_t DTYPE_t
@cython.boundscheck(False)
def fix_zeroes(np.ndarray[DTYPE_t, ndim=1] raw):
assert raw.dtype == DTYPE
cdef int len = 50000
for x in range(2,len):
if raw[x] == 0 and raw[x-1] == 0:
raw[x] = (raw[x-2] + raw[x+2]) / 2
raw[x-1] = (raw[x-3] + raw[x+1]) /2
return raw
当我运行这段代码时,性能仍然比我希望的要慢很多:
开始修复零值
完成:0:00:36.983681
开始Python修复零值
完成:0:00:41.434476
我真的觉得我可能做错了什么。我看到的大多数文章都在讲numpy和cython能带来巨大的性能提升,但我几乎没有超过10%的提升。
1 个回答
7
你应该先声明一下你用来索引 raw
数组的 x
变量:
cdef int x
你还可以使用其他一些指令,这些指令通常能提高性能:
@cython.wraparound(False)
@cython.cdivision(True)
@cython.nonecheck(False)