【发布时间】:2014-05-08 18:58:57
【问题描述】:
我有一个非常简单的功能,我需要加快速度。本质上,我有一大堆 16 位数字,其中有一些孔。 (大约 10%)我需要遍历数组,找到连续有 2 个 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
当我运行这段代码时,性能仍然比我想要的慢:
开始 cython 零修复
完成:0:00:36.983681
启动 python 零修复
完成:0:00:41.434476
我真的认为我一定做错了什么。我看过的大多数文章都谈到了 numpy 和 cython 的巨大性能提升,但我几乎没有突破 10%。
【问题讨论】:
-
This takes only a few milliseconds in C。你有C函数吗?如果是这样,只需将其直接包装在 Cython 中并从您的 Python 程序中调用它。 -
@ThaneBrimhall 使用 Cython 以及所有增强指令和类型声明应该非常接近 C
-
@ThaneBrimhall - 好点。我有一个 C 函数,但它是一团糟。我需要重写算法,这是无论如何的一部分,所以这就是它被移植到 python 的原因。不过我确实喜欢你的建议。
-
@SaulloCastro 是的,我知道。但是我很懒,如果我已经完成了一些事情,我通常只是重复使用它。 ;)
标签: python arrays numpy cython