Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么cffi比numpy快得多?_Python_C_Numpy_Pypy_Python Cffi - Fatal编程技术网

Python 为什么cffi比numpy快得多?

Python 为什么cffi比numpy快得多?,python,c,numpy,pypy,python-cffi,Python,C,Numpy,Pypy,Python Cffi,我一直在用python编写cffi模块,它们的速度让我怀疑我是否正确使用了标准python。这让我想完全切换到C!老实说,有一些很棒的python库我自己永远无法用C重新实现,所以这更像是一种假设 这个例子展示了python中与numpy数组一起使用的sum函数,以及它与c函数相比有多慢。有没有一种更快的pythonic方法来计算numpy数组的和 def cast_matrix(matrix, ffi): ap = ffi.new("double* [%d]" % (matrix.sh

我一直在用python编写cffi模块,它们的速度让我怀疑我是否正确使用了标准python。这让我想完全切换到C!老实说,有一些很棒的python库我自己永远无法用C重新实现,所以这更像是一种假设

这个例子展示了python中与numpy数组一起使用的sum函数,以及它与c函数相比有多慢。有没有一种更快的pythonic方法来计算numpy数组的和

def cast_matrix(matrix, ffi):
    ap = ffi.new("double* [%d]" % (matrix.shape[0]))
    ptr = ffi.cast("double *", matrix.ctypes.data)
    for i in range(matrix.shape[0]):
        ap[i] = ptr + i*matrix.shape[1]                                                                
    return ap 

ffi = FFI()
ffi.cdef("""
double sum(double**, int, int);
""")
C = ffi.verify("""
double sum(double** matrix,int x, int y){
    int i, j; 
    double sum = 0.0;
    for (i=0; i<x; i++){
        for (j=0; j<y; j++){
            sum = sum + matrix[i][j];
        }
    }
    return(sum);
}
""")
m = np.ones(shape=(10,10))
print 'numpy says', m.sum()

m_p = cast_matrix(m, ffi)

sm = C.sum(m_p, m.shape[0], m.shape[1])
print 'cffi says', sm
现在,如果我计时这个简单的函数,我发现numpy真的很慢! 我使用numpy的方式正确吗?在python中有没有更快的方法来计算总和

import time
n = 1000000

t0 = time.time()
for i in range(n): C.sum(m_p, m.shape[0], m.shape[1])
t1 = time.time()

print 'cffi', t1-t0

t0 = time.time()
for i in range(n): m.sum()
t1 = time.time()

print 'numpy', t1-t0
时代:

cffi 0.818415880203
numpy 5.61657714844

Numpy比C慢有两个原因:Python开销(可能类似于cffi)和通用性。Numpy设计用于处理不同数据类型中的任意维数组。您的cffi示例是针对二维浮点数阵列制作的。成本是编写几行代码vs
.sum()
,6个字符以节省不到5微秒的时间。(当然,你已经知道了这一点)。我只想强调,CPU时间很便宜,比开发人员的时间便宜得多

现在,如果您想坚持使用Numpy,并且希望获得更好的性能,那么最好的选择就是使用。它们提供了一些功能,针对浮点和双精度的1和2D阵列进行了优化,而且速度非常快。在您的情况下,速度提高了16倍,这将使执行时间提高到0.35,大约是cffi的两倍


对于瓶颈没有的其他功能,可以使用Cython。它可以帮助您使用更pythonic的语法编写C代码。或者,如果愿意,可以逐步将Python转换为C,直到您对速度感到满意。

使用该模块进行基准测试。如果您安装了ipython,请尝试
%timeit np.sum(np.sum(m))
和`%timeit np.matrix.sum(x)`可能主要来自python开销,使用较大的数组(如
1E3x1E3
尝试此操作,并减少循环次数将看到更多的可比时间。请注意,如果您直接使用瓶颈的专用函数,相对于Numpy,速度提高了约25倍。您的cffi现在在哪里?:)除了nan的运算外,这似乎比numpy的总和快不了多少。这里的关键似乎是通过预选底层的C函数来避免python开销。Numpy是否公开了专门的功能?您总是可以从C API调用它们,但是您需要通过Cython。另外,签出numba。
cffi 0.818415880203
numpy 5.61657714844