为什么cffi比numpy快得多?[英] Why is cffi so much quicker than numpy?

本文是小编为大家收集整理的关于为什么cffi比numpy快得多?的处理方法,想解了为什么cffi比numpy快得多?的问题怎么解决?为什么cffi比numpy快得多?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我一直在尝试用 python 编写 cffi 模块,它们的速度让我怀疑我是否正确使用了标准 python.这让我想完全切换到C!说实话,有一些很棒的 python 库我永远无法用 C 重新实现自己,所以这比任何事情都更具假设性.

这个例子展示了 python 中的 sum 函数与一个 numpy 数组一起使用,以及它与 c 函数相比有多慢.有没有更快的 Python 方法来计算 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 says 100.0
cffi says 100.0

现在,如果我对这个简单的函数计时,我发现 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,并且想要获得更好的性能,最好的选择是使用 瓶颈.它们提供了一些针对浮点数和双精度数的一维和二维数组优化的函数,而且速度非常快.在您的情况下,速度提高了 16 倍,这将使执行时间缩短为 0.35,或大约是 cffi 的两倍.

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

本文地址:https://www.itbaoku.cn/post/359038.html