NumPy vs Cython - 嵌套循环这么慢?

Mar*_*urz 4 python numpy

我很困惑,与Cython相比,NumPy嵌套循环的3D数组是如此之慢.我写了一些简单的例子.

Python/NumPy版本:

import numpy as np

def my_func(a,b,c):
    s=0
        for z in xrange(401):
        for y in xrange(401):
            for x in xrange(401):
                if a[z,y,x] == 0 and b[x,y,z] >= 0:
                    c[z,y,x] = 1
                    b[z,y,x] = z*y*x
                    s+=1
    return s

a = np.zeros((401,401,401), dtype=np.float32)
b = np.zeros((401,401,401), dtype=np.uint32)
c = np.zeros((401,401,401), dtype=np.uint8)

s = my_func(a,b,c)
Run Code Online (Sandbox Code Playgroud)

Cythonized版本:

cimport numpy as np
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
def my_func(np.float32_t[:,:,::1] a, np.uint32_t[:,:,::1] b, np.uint8_t[:,:,::1] c):
    cdef np.uint16_t z,y,x
    cdef np.uint32_t s = 0

    for z in range(401):
        for y in range(401):
            for x in range(401):
                if a[z,y,x] == 0 and b[x,y,z] >= 0:
                    c[z,y,x] = 1
                    b[z,y,x] = z*y*x
                    s = s+1
    return s
Run Code Online (Sandbox Code Playgroud)

Cythonized版本的my_func()运行约.快6500倍.仅使用if语句和数组访问的简单函数甚至可以快10000倍.Python版本my_func()需要500.651秒.完成.迭代相对较小的3D阵列这么慢还是我在代码中犯了一些错误?

Cython版本0.21.1,Python 2.7.5,GCC 4.8.1,Xubuntu 13.10.

Kru*_*lur 5

Python是一种解释型语言.编译到机器代码的好处之一是你获得的巨大加速,尤其是嵌套循环之类的东西.

我不知道你的期望是什么,但所有解释的语言在你想要做的事情上会非常慢(JIT编译可能在某种程度上有所帮助).

从Numpy(或MATLAB或类似的东西)中获得良好性能的技巧是完全避免循环,而是尝试将代码重构为大型矩阵上的一些操作.这样,循环将在(经过大量优化的)机器代码库中进行,而不是在Python代码中进行.