我对Python相当陌生,而且对C一无所知(不幸的是),所以我正努力正确理解使用Cython的某些方面。在
在分析了一个Python程序并发现大部分时间只占用了几个循环之后,我决定考虑将它们转储到Cython中。最初,我让Cython按原样解释Python,结果是a(了不起!)~2倍速度提升。酷!在
在Python main中,我向函数传递两个二维数组(“a”和“b”)和一个浮点“D”,它返回一个列表“newlist”。例如:a =[[12.7, 13.5, 1.0],[23.4, 43.1, 1.0],...]
b =[[0.46,0.95,0],[4.56,0.92,0],...]
d = 0.1
以下是原始代码,只为Cython添加了cdefs:
^{pr2}$
在“纯Python”中,它在大约12.5s内运行(有几万个循环),在Cython中它运行了~6.3s。取得了巨大的进步,几乎完成了零个工作!在
不过,只要稍加阅读,就可以清楚地看到还有很多很多事情要做,所以我开始尝试应用一些类型更改,以使事情进行得更快,遵循Cython文档here(也在注释中引用)。在
以下是收集的修改,旨在模仿Cython文档:import numpy as np
cimport numpy as np
DtypeA = np.float
DtypeB = np.int
ctypedef np.float_t DtypeA_t
ctypedef np.int_t DtypeB_t
def loop(np.ndarray[DtypeA_t, ndim=2] A,
np.ndarray[DtypeA_t, ndim=2] B,
np.ndarray[DtypeB_t, ndim=1] C,
float D):
cdef Py_ssize_t i, j
cdef float x, y
cdef np.ndarray[DtypeA_t, ndim=2] NEW_ARRAY = np.zeros((len(C),3), dtype=DtypeA)
for i in range(len(C)):
if C[i] != 1:
for j in range(i+1,len(C)):
if A[i][0]==A[j][0] and A[i][1]==A[j][1] and C[j]!= 1:
x = B[i][0]+B[j][0]
y = B[i][1]+B[j][1]
C[i],C[j] = 1,1
if abs(y)/abs(x) > D:
if y > 0: NEW_ARRAY[i]=([A[i][0],A[i][1],y])
return NEW_ARRAY
除此之外,我将前面的数组“b”拆分为两个不同的输入数组“b”和“C”,因为“b”的每一行包含2个浮点元素和一个充当标志的整数。所以我去掉了标志整数,把它们放在一个单独的一维数组“C”中。所以,现在的输入看起来是这样的:A =[[12.7, 13.5, 1.0],[23.4, 43.1, 1.0],...]
B =[[0.46,0.95],[4.56,0.92],...]
C =[0,0,...]
D = 0.1
理想情况下,如果所有变量都被输入(?)。。。但是很明显我做了一件非常错误的事情,因为这个函数现在在35.3秒的时候出现了……比“纯Python”还要糟糕!!在
我怎么搞砸了?谢谢你的阅读!在