添加cython比numpy慢的数组?

kez*_*zos 4 python arrays numpy cython

我刚刚开始学习cython,所以请原谅我的无知.简单地将两个数组一起添加,cython可以改进numpy吗?我非常糟糕地尝试添加两个数组a + b来给出一个新的数组c:

import numpy as np
cimport numpy as np

DTYPE = np.int
ctypedef np.int_t DTYPE_t

def add_arrays(np.ndarray[DTYPE_t, ndim=2] a, np.ndarray[DTYPE_t, ndim=2] b, np.ndarray[DTYPE_t, ndim=2] c):
    cdef int x = a.shape[0]
    cdef int y = a.shape[1]
    cdef int val_a
    cdef int val_b
    for j in range(x):
        for k in range(y):
            val_a = a[j][k]
            val_b = b[j][k]
            c[j][k] = val_a + val_b    
    return c
Run Code Online (Sandbox Code Playgroud)

但是,当传递这些数组时,此版本的速度要慢700倍(*edit:而不是numpy):

n = 1000 
a = np.ones((n, n), dtype=np.int)
b = np.ones((n, n), dtype=np.int)
c = np.zeros((n, n), dtype=np.int)
Run Code Online (Sandbox Code Playgroud)

我显然缺少一些非常大的东西.

Sau*_*tro 6

问题是你正在索引2-D数组,就像c[j][k]你应该做的那样c[j,k],否则Cython正在使用一个中间缓冲区buf=c[j],它将从中获取buf[k],导致速度减慢.您应该使用这个正确的索引以及cdef@XavierCombelle指定的声明.

您可以通过执行以下操作来检查此中间缓冲区是否导致速度减慢:

np.ndarray[DTYPE_t, ndim=1] buf
Run Code Online (Sandbox Code Playgroud)

然后,在循环内:

buf = c[j]
buf[k] = val_a + val_b
Run Code Online (Sandbox Code Playgroud)

这个声明的缓冲区应该提供与以下相同的速度(或接近):

c[j,k] = val_a + val_b
Run Code Online (Sandbox Code Playgroud)