这些都是bubblesort实现的不同风格,n = 10 ^ 4的最快方法是在内部将Python列表转换为C数组。相反,黄线对应于我正在使用带有memoryview的NumPy数组的代码。我预计结果反之亦然。我(及其同事)重复了几次基准测试,并始终得到相同的结果。也许有人知道这里发生了什么......
图中的黑线对应于代码:
%%cython
cimport cython
from libc.stdlib cimport malloc, free
def cython_bubblesort_clist(a_list):
"""
The Cython implementation of bubble sort with internal
conversion between Python list objects and C arrays.
"""
cdef int *c_list
c_list = <int *>malloc(len(a_list)*cython.sizeof(int))
cdef int count, i, j # static type declarations
count = len(a_list)
# convert Python list to C array
for i in range(count):
c_list[i] = a_list[i]
for i in range(count):
for j in range(1, count):
if c_list[j] < c_list[j-1]:
c_list[j-1], c_list[j] = c_list[j], c_list[j-1]
# convert C array back to Python list
for i in range(count):
a_list[i] = c_list[i]
free(c_list)
return a_list
和此代码的粉色线:
%%cython
import numpy as np
cimport numpy as np
cimport cython
def cython_bubblesort_numpy(long[:] np_ary):
"""
The Cython implementation of bubble sort with NumPy memoryview.
"""
cdef int count, i, j # static type declarations
count = np_ary.shape[0]
for i in range(count):
for j in range(1, count):
if np_ary[j] < np_ary[j-1]:
np_ary[j-1], np_ary[j] = np_ary[j], np_ary[j-1]
return np.asarray(np_ary)
答案 0 :(得分:3)
正如上面的评论所示,我添加了装饰器
%%cython
import numpy as np
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef cython_bubblesort_numpy(long[:] np_ary):
"""
The Cython implementation of bubble sort with NumPy memoryview.
"""
cdef int count, i, j # static type declarations
count = np_ary.shape[0]
for i in range(count):
for j in range(1, count):
if np_ary[j] < np_ary[j-1]:
np_ary[j-1], np_ary[j] = np_ary[j], np_ary[j-1]
return np.asarray(np_ary)
结果更符合我的预期:)
答案 1 :(得分:1)
值得对代码进行一次微不足道的更改,看看它是否能进一步改进:
cpdef cython_bubblesort_numpy(long[::1] np_ary):
# ...
这告诉cython np_ary
是一个 C连续的数组,嵌套的for
循环中生成的代码可以使用这些信息进一步优化。
此代码不接受非连续数组作为参数,但使用numpy.ascontiguousarray()
处理这一点非常简单。