【发布时间】:2013-09-27 02:22:19
【问题描述】:
TLDR:在 cython 中,为什么(或何时?)迭代 numpy 数组比迭代 python 列表更快?
通常: 我以前使用过 Cython,并且能够在幼稚的 python impl' 上获得巨大的加速, 然而,弄清楚究竟需要做什么似乎并非易事。
考虑以下 3 个 sum() 函数的实现。 它们驻留在一个名为“cy”的 cython 文件中(显然,有 np.sum(),但这不是我的意思..)
天真的蟒蛇:
def sum_naive(A):
s = 0
for a in A:
s += a
return s
具有需要 python 列表的函数的 Cython:
def sum_list(A):
cdef unsigned long s = 0
for a in A:
s += a
return s
具有需要 numpy 数组的函数的 Cython。
def sum_np(np.ndarray[np.int64_t, ndim=1] A):
cdef unsigned long s = 0
for a in A:
s += a
return s
我希望就运行时间而言,sum_np ,但是,下面的脚本却相反(为了完整性,我添加了 np.sum() )
N = 1000000
v_np = np.array(range(N))
v_list = range(N)
%timeit cy.sum_naive(v_list)
%timeit cy.sum_naive(v_np)
%timeit cy.sum_list(v_list)
%timeit cy.sum_np(v_np)
%timeit v_np.sum()
结果:
In [18]: %timeit cyMatching.sum_naive(v_list)
100 loops, best of 3: 18.7 ms per loop
In [19]: %timeit cyMatching.sum_naive(v_np)
1 loops, best of 3: 389 ms per loop
In [20]: %timeit cyMatching.sum_list(v_list)
10 loops, best of 3: 82.9 ms per loop
In [21]: %timeit cyMatching.sum_np(v_np)
1 loops, best of 3: 1.14 s per loop
In [22]: %timeit v_np.sum()
1000 loops, best of 3: 659 us per loop
发生了什么事? 为什么 cython+numpy 慢?
附言
我确实使用
#cython: boundscheck=False
#cython: wraparound=False
【问题讨论】:
-
我不知道 cython 是否可以加快数组的
for a in A类型循环,也许输入a会解决问题。我相信,尽管正确(或至少更常见)加快速度的方法是:cdef int j; for j in range(len(A)): s += A[j].
标签: python arrays optimization numpy cython