2011-12-05 9 views
25

Acabo de cambiar un programa que estoy escribiendo para mantener mis datos como matrices numpy ya que tenía problemas de rendimiento, y la diferencia fue increíble. Originalmente tomó 30 minutos para ejecutarse y ahora demora 2.5 segundos.¿Por qué las matrices NumPy son tan rápidas?

Me preguntaba cómo lo hace. Supongo que es así porque elimina la necesidad de los bucles for, pero más allá de eso estoy perplejo.

+4

Supongo que es porque las matrices numpy están implementadas en C en lugar de en Python. –

+7

@NoufalIbrahim: las listas de Python también se implementan en C] (http://stackoverflow.com/questions/3917574/how-is-pythons-list-implemented/3958322#3958322). –

+7

Pregunta bastante vaga sin ninguna indicación de qué estaban haciendo los dos programas y cómo se implementaron. –

Respuesta

52

Las matrices numeradas son matrices densamente compactas de tipo homogéneo. Las listas de Python, por el contrario, son matrices de punteros a objetos, incluso cuando todos ellos son del mismo tipo. Entonces, obtienes los beneficios de locality of reference.

Además, muchas operaciones de Numpy se implementan en C, lo que evita el costo general de los bucles en Python, la indirección del puntero y la comprobación del tipo dinámico por elemento. El aumento de velocidad depende de las operaciones que esté realizando, pero algunos órdenes de magnitud no son infrecuentes en los programas de procesamiento de números.

+1

¿Cómo es posible ofrecer el front-end de Python para estas operaciones escritas en C? ¿Cómo se llama esta técnica? –

+0

Esto no puede ser cierto. Las listas de Python no son matrices de punteros cuando los elementos son tipos primitivos, como enteros. Una manera rápida de probar eso es guardar un número en una variable y formar una matriz con esa variable. Si cambia la variable, la matriz no cambia. – Rohan

+0

@Rohan Recuerda que incluso los tipos primitivos son objetos. Entonces, cuando agregaste esa variable a la lista, realmente solo estás agregando el objeto al que apunta esa variable en particular a la lista. En este caso, este objeto es un número. Entonces, cuando cambia la variable, o más precisamente, vuelve a enlazar el nombre a un nuevo entero, no está cambiando las propiedades del objeto original, es decir, el número original. Por lo tanto, se espera que el número "correspondiente" en la matriz no cambie su valor. – Kun

1

Las matrices numeradas son extremadamente similares a las matrices "normales" como las de c. Tenga en cuenta que cada elemento debe ser del mismo tipo. La aceleración es excelente porque puede aprovechar la captación previa y puede acceder instantáneamente a cualquier elemento en la matriz por su índice.

+0

¿Podría explicar cómo tener el mismo tipo para cada elemento hace que los cálculos sean más rápidos? – Rohan

9

numpy arrays son estructuras de datos especializadas. Esto significa que no solo obtendrá los beneficios de una representación eficiente en memoria, sino también implementaciones especializadas eficientes.

E.g. si está sumando dos matrices, la adición se realizará con las operaciones de vector de CPU especializadas, en lugar de llamar a la implementación python de la suma int en un bucle.

+1

Estas (operaciones especializadas y optimización dinámica) son las respuestas correctas.Factores menores como la precarga y la localidad de referencia solo se vuelven significativos después de que se abordan los principales factores de rendimiento (sobrecarga del intérprete). – Dave

+2

ubicación de referencia es importante por dos razones: debido a la localidad misma (y sus efectos sobre el almacenamiento en caché), y porque la falta de direccionamiento indirecto significa que las instrucciones para procesar la dirección indirecta se pueden omitir. –

1

Aún tiene bucles, pero están hechos en c. Numpy se basa en Atlas, que es una biblioteca para operaciones de álgebra lineal.

http://math-atlas.sourceforge.net/

Cuando se enfrenta a un gran cálculo, se ejecutará pruebas con varias implementaciones para averiguar cuál es el más rápido en nuestro equipo en este momento. Con algunas construcciones numpy, las comutaciones se pueden paralelizar en múltiples cpus. Por lo tanto, tendrá una ejecución c altamente optimizada en bloques de memoria continua.

+5

Numpy no está basado en Atlas. Puede utilizar, si está disponible, una implementación de BLAS para un subconjunto muy, muy pequeño de su funcionalidad (básicamente dot, gemv y gemm). Ese BLAS puede ser el BLAS de referencia incorporado con el que se envía, o Atlas, o Intel MKL (la distribución prevista está construida con esto). – talonmies

Cuestiones relacionadas