将某些Cython变量从类型int
更改为类型size_t
可以显著减少某些函数的运行时间(约30%),但我不知道为什么。
例如:
cimport numpy as cnp
import numpy as np
def sum_int(cnp.int64_t[::1] A):
cdef unsigned long s = 0
cdef int k
for k in xrange(A.shape[0]):
s += A[k]
return s
def sum_size_t(cnp.int64_t[::1] A):
cdef unsigned long s = 0
cdef size_t k
for k in xrange(A.shape[0]):
s += A[k]
return s
a = np.array(range(1000000))
接下来是时间结果:
In [17]: %timeit sum_int(a)
1000 loops, best of 3: 652 µs per loop
In [18]: %timeit sum_size_t(a)
1000 loops, best of 3: 427 µs per loop
我刚接触Cython,但是比起C语言更熟悉Fortran。请帮我解答一下,这两种变量类型之间的重要区别导致了如此大的性能差异?我对Cython还有哪些方面不太了解呢?
int64_t
数组。为什么不在累加器中使用int64_t
呢? - user2357112size_t
不是隐式无符号的吗?由于您在循环中使用变量k
,我猜如果您使用size_t
或无符号整数,它会被优化,因为Cython文档报告说“当索引值已由cdef声明时,例如,'range()'是C优化的”。所以,您后面用作A
索引器的无符号值永远不会为负(并且它应该允许您将wraparound
和boundscheck
参数设置为False
,因为您正在安全地循环遍历数组的边界,并且可能具有更好的性能)? - mgcunsigned int
代替int
,几乎接近于size_t
的速度。不过仍然只有大约80%的速度。如此接近! - john_science