Pergunta

Eu fui brincar com a escrita cffi módulos em python, e sua velocidade é me perguntar se eu estou usando o padrão do python corretamente.Ele está me fazendo querer mudar para C completamente!Sinceramente, há algumas grandes bibliotecas python eu nunca poderia implementar mim em C, então este é mais hipotético do que qualquer coisa realmente.

Este exemplo mostra que a soma de função em python que está sendo usado com um numpy matriz, e lento como é em comparação com uma função c.Existe um modo mais rápido pythonic maneira de computar a soma de uma numpy matriz?

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

apenas para mostrar que a função funciona:

numpy says 100.0
cffi says 100.0

agora, se eu o tempo esta simples função de eu achar que o numpy é muito lento!Estou usando o numpy da maneira correta?Existe uma forma mais rápida para calcular a soma em 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

horários:

cffi 0.818415880203
numpy 5.61657714844
Foi útil?

Solução

Numpy é mais lento do que o C, por duas razões:o Python sobrecarga (provavelmente semelhante à cffi) e generalidade.Numpy é projetado para lidar com matrizes de dimensões arbitrárias, em um monte de diferentes tipos de dados.O seu exemplo com cffi foi feita para um array 2D de carros alegóricos.O custo foi de escrever várias linhas de código vs .sum(), 6 caracteres para salvar a menos de 5 microssegundos.(Mas, claro, você já sabia disso).Eu só quero enfatizar que o tempo de CPU é barato, muito mais barato do que o desenvolvedor do tempo.

Agora, se você quiser ficar para Numpy, e você deseja obter um melhor desempenho, sua melhor opção é usar Gargalo.Eles fornecem algumas funções optimizadas para 1 e 2D matrizes de flutuar e duplas, e eles são super rápida.No seu caso, 16 vezes mais rápida, que irá colocar o tempo de execução de 0,35, ou cerca de duas vezes tão rápido como cffi.

Para outras funções que o gargalo não tem, você pode usar Cython.Ele ajuda você a escrever códigos em C, com mais de pythonic sintaxe.Ou, se quiser, converter progressivamente Python em C até que você esteja satisfeito com a velocidade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top