【发布时间】:2020-03-31 11:15:26
【问题描述】:
我想使用 Cython 来减少将两个数组添加在一起(按元素)而不使用 Numpy 数组所需的时间。我发现最快的基本 Python 方法是使用列表推导,如下所示:
def add_arrays(a,b):
return [m + n for m,n in zip(a,b)]
我的 Cython 方法有点复杂,如下所示:
from array import array
from libc.stdlib cimport malloc
from cython cimport boundscheck,wraparound
@boundscheck(False)
@wraparound(False)
cpdef add_arrays_Cython(int[:] Aarr, int[:] Barr):
cdef size_t i, I
I = Aarr.shape[0]
cdef int *Carr = <int *> malloc(640000 * sizeof(int))
for i in range(I):
Carr[i] = Aarr[i]+Barr[i]
result_as_array = array('i',[e for e in Carr[:640000]])
return result_as_array
请注意,我使用@boundscheck(False) 和@wraparound(False) 使其更快。
另外,我担心一个非常大的数组(大小为 640000),如果我只使用cdef int Carr[640000],我发现它会崩溃,所以我使用了malloc(),它解决了这个问题。最后,我将数据结构作为整数类型的 Python 数组返回。
为了分析我运行的代码:
a = array.array('i', range(640000)) #create integer array
b = a[:] #array to add
T=time.clock()
for i in range(20): add_arrays(a,b) #Python list comprehension approach
print(time.clock() - T)
>6.33 秒
T=time.clock()
for i in range(20): add_arrays_Cython(a,b) #Cython approach
print(time.clock() - T)
> 4.54 秒
显然,基于 Cython 的方法可以提高大约 30% 的速度。我预计加速会接近一个数量级甚至更多(就像它对 Numpy 所做的那样)。
如何进一步加快 Cython 代码的速度?我的代码中是否有任何明显的瓶颈? 我是 Cython 的初学者,所以我可能会误解一些东西。
【问题讨论】:
-
确保描述清楚地说明您使用 Python
list与array.array的时间。numpy在很大程度上取代了内置的array包。我不知道cython实现它的效果如何。为了最大限度地提高速度,请考虑使用array's缓冲区接口和cython'styped memoryview。