我希望使用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 seconds
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的初学者,可能有误解。
list
和array.array
。numpy
在很大程度上取代了内置的array
包。我不知道cython
实现得有多好。为了最大化速度,请考虑使用array
的缓冲区接口以及cython
的typed memoryview
。 - hpaulj