¿Qué herramientas o enfoques están disponibles para acelerar el código escrito en Python?


29

Antecedentes: creo que podría querer portar algún código que calcule productos de vectores exponenciales de matriz utilizando un método de subespacio Krylov de MATLAB a Python. (Específicamente, la función expmvp de Jitse Niesen , que utiliza un algoritmo descrito en este documento ). Sin embargo, sé que a menos que haga un uso intensivo de las funciones de los módulos derivados de bibliotecas compiladas (es decir, solo uso Python sin formato, y no muchos en funciones), entonces podría ser bastante lento.

Pregunta: ¿Qué herramientas o enfoques están disponibles para ayudarme a acelerar el código que escribo en Python para el rendimiento? En particular, estoy interesado en herramientas que automaticen el proceso tanto como sea posible, aunque los enfoques generales también son bienvenidos.

Nota: Tengo una versión anterior del algoritmo de Jitse y no la he usado en mucho tiempo. Podría ser muy fácil hacer que este código sea rápido, pero sentí que sería un buen ejemplo concreto y está relacionado con mi propia investigación. Debatir mi enfoque para implementar este algoritmo particular en Python es otra cuestión completamente diferente.


Di una respuesta específica de Python a esta pregunta: scicomp.stackexchange.com/questions/2429/… Creo que las sugerencias y los enlaces allí serán útiles para usted.
AlexE

(h / t a @AlexE por hacerme consciente de esto) Definitivamente hay una superposición entre esta pregunta, (¿cómo) escribir simulaciones que se ejecutan más rápido? y ¿Cuáles son algunas buenas estrategias para mejorar el rendimiento en serie de mi código? . Algún tipo de fusión podría estar en orden. Publiqué sobre eso en Meta.
Geoff Oxberry

1
Además de las buenas respuestas aquí, eche un vistazo a este enlace .
Mike Dunlavey

Respuestas:


40

Voy a dividir mi respuesta en tres partes. Perfilado, acelerando el código de python a través de c, y acelerando python a través de python. En mi opinión, Python tiene algunas de las mejores herramientas para ver cuál es el rendimiento de su código y luego profundizar en los cuellos de botella reales. Acelerar el código sin perfilar es como tratar de matar a un ciervo con un uzi.

Si realmente solo está interesado en los productos mat-vec, le recomendaría scipy.sparse .

Herramientas de Python para perfilar

módulos de perfil y perfil c : estos módulos le proporcionarán su análisis de tiempo de ejecución estándar y la pila de llamadas de función. Es bastante agradable guardar sus estadísticas y usar el módulo pstats puede ver los datos de varias maneras.

kernprof : esta herramienta reúne muchas rutinas para hacer cosas como la sincronización de código línea por línea

memory_profiler : esta herramienta produce una huella de memoria línea por línea de su código.

Temporizadores de IPython : latimeitfunción es bastante agradable para ver las diferencias en las funciones de una manera interactiva rápida.

Acelerando Python

Cython : cython es la forma más rápida de tomar algunas funciones en python y obtener un código más rápido. Puede decorar la función con la variante cython de python y genera código c. Esto es muy fácil de mantener y también puede vincularse a otro código escrito a mano en c / c ++ / fortran con bastante facilidad. Es, con mucho, la herramienta preferida hoy en día.

ctypes : ctypes le permitirá escribir sus funciones en c y luego envolverlas rápidamente con su simple decoración del código. Maneja todo el dolor de enviar desde PyObjects y administrar el gil para llamar a la función c.

Existen otros enfoques para escribir su código en C, pero todos son algo más para tomar una biblioteca C / C ++ y envolverla en Python.

Enfoques solo para Python

Si desea permanecer dentro de Python principalmente, mi consejo es averiguar qué datos está utilizando y elegir los tipos de datos correctos para implementar sus algoritmos. Según mi experiencia, por lo general, llegarás mucho más lejos al optimizar tus estructuras de datos que cualquier pirateo de bajo nivel. Por ejemplo:

numpy : una matriz continua muy rápida para operaciones de arrays

numexpr : un optimizador de expresiones de matriz numpy. Permite expresiones de matriz numpy de subprocesos múltiples y también elimina los numerosos temporales que hace numpy debido a las restricciones del intérprete de Python.

blist : una implementación de b-tree de una lista, muy rápida para insertar, indexar y mover los nodos internos de una lista

pandas : marcos de datos (o tablas) análisis muy rápidos en las matrices.

pytables : tablas jerárquicas estructuradas rápidas (como hdf5), especialmente buenas para cálculos y consultas fuera de núcleo a datos grandes.


3
También puede usar ctypes para llamar a las rutinas de Fortran.
Matthew Emmett


Hablando de código de ajuste, ¿qué pasa con f2py?
astrojuanlu

f2py es una gran herramienta y utilizada por muchos en la comunidad. fwrap es un reemplazo más reciente ya que f2py muestra su antigüedad pero no está realmente completo.
aterrel

¡Gracias! Estos son los tipos de recursos que estaba buscando. Solo conocía algunos de ellos, y solo de pasada (o al mirarlos en Internet). Aron sigue mencionando numexpr. ¿Cómo funciona? ¿Se aplicaría eso?
Geoff Oxberry

7

En primer lugar, si hay una implementación de C o Fortran disponible (¿función MATLAB MEX?), ¿Por qué no escribe un contenedor de Python?

Si desea su propia implementación, no solo un contenedor, sugeriría encarecidamente utilizar el módulo numpy para cosas de álgebra lineal. Asegúrese de que esté vinculado a un blas optimizado (como ATLAS, GOTOblas, uBLAS, Intel MKL, ...). Y usa Cython o tejido. Lea este artículo de Performance Python para una buena introducción y punto de referencia. Las diferentes implementaciones en este artículo están disponibles para descargar aquí, cortesía de Travis Oliphant (Numpy-guru).

Buena suerte.


Ese artículo de Performance Python parece un poco anticuado, no menciona algunas de las herramientas más nuevas disponibles como numexpr.
Aron Ahmadia

De hecho, pasé por alto numexpr. Sería bueno ejecutar el mismo punto de referencia de Laplace con numexpr ...
GertVdE

¿ scipy.weaveTodavía se usa y se desarrolla? Parece que el artículo de Performance Python muestra que podría ser rápido de usar y ofrece una mejora bastante buena en la velocidad, pero rara vez lo he visto mencionado fuera de ese artículo.
Ken

@Ken: scipy.weave, por lo que sé, ya no está en desarrollo activo. Se mantiene por compatibilidad con versiones anteriores, pero se alienta a los nuevos proyectos a utilizar Cython.
GertVdE


4

Básicamente estoy de acuerdo con las otras respuestas. Las mejores opciones para un código numérico rápido pythonson

  • Use bibliotecas especializadas como numpy
  • pythonajusta tu código existente para que tu programa pueda llamarlo directamente

Pero si desea programar todo el algoritmo desde cero (cito: "Solo uso Python en bruto"), entonces puede considerar http://pypy.org/ una implementación JIT (Just In Time) de python. No he podido usarlo para mi proyecto (porque eso depende numpyy los pypychicos están trabajando actualmente para apoyar eso) pero los puntos de referencia son bastante impresionantes ( http://speed.pypy.org/ )


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.