¿Por qué cffi es mucho más rápido que numpy?

He estado jugando escribiendo módulos cffi en python, y su velocidad me hace preguntarme si estoy usando python estándar correctamente. ¡Me está haciendo querer cambiar a C por completo! A decir verdad, hay algunas excelentes bibliotecas de Python que nunca podría volver a implementar en C, por lo que esto es más hipotético que cualquier otra cosa.

Este ejemplo muestra la función de suma en python que se usa con una matriz numpy, y qué tan lenta es en comparación con una función c. ¿Existe una forma pitónica más rápida de calcular la suma de una matriz 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

solo para mostrar que la función funciona:

numpy says 100.0
cffi says 100.0

¡ahora si cronometro esta simple función, encuentro que numpy es realmente lento! ¿Estoy usando numpy de la manera correcta? ¿Hay una forma más rápida de calcular la suma en 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

veces:

cffi 0.818415880203
numpy 5.61657714844

Respuestas a la pregunta(1)

Su respuesta a la pregunta