Contexte: Je pense que je pourrais vouloir porter du code qui calcule les produits matriciels à vecteur exponentiel en utilisant une méthode de sous-espace Krylov de MATLAB à Python. (Plus précisément, la fonction expmvp de Jitse Niesen , qui utilise un algorithme décrit dans cet article .) Cependant, je sais qu'à moins que j'utilise intensivement les fonctions des modules dérivés des bibliothèques compilées (c'est-à-dire que j'utilise uniquement du Python brut et pas beaucoup de dans les fonctions), cela pourrait être assez lent.
Question: Quels outils ou approches sont disponibles pour m'aider à accélérer le code que j'écris en Python pour les performances? En particulier, je m'intéresse aux outils qui automatisent le plus possible le processus, bien que les approches générales soient également les bienvenues.
Remarque: J'ai une ancienne version de l'algorithme de Jitse et je ne l'ai pas utilisée depuis un moment. Il pourrait être très facile de rendre ce code rapide, mais je pensais que ce serait un bon exemple concret, et il est lié à mes propres recherches. Débattre de mon approche pour implémenter cet algorithme particulier en Python est une autre question entièrement.
la source
Réponses:
Je vais diviser ma réponse en trois parties. Profilage, accélération du code python via c et accélération de python via python. À mon avis, Python possède certains des meilleurs outils pour analyser les performances de votre code, puis remonter jusqu'aux goulots d'étranglement. Accélérer le code sans profiler, c'est comme essayer de tuer un cerf avec un uzi.
Si vous n'êtes vraiment intéressé que par les produits mat-vec, je recommanderais scipy.sparse .
Outils Python pour le profilage
modules de profil et cProfile : Ces modules vous donneront votre analyse d'exécution standard et votre pile d'appels de fonctions. Il est assez agréable d'enregistrer leurs statistiques et en utilisant le module pstats, vous pouvez consulter les données de plusieurs façons.
kernprof : cet outil rassemble de nombreuses routines pour faire des choses comme le minutage du code ligne par ligne
memory_profiler : cet outil produit une empreinte mémoire ligne par ligne de votre code.
Minuteries IPython : La
timeit
fonction est assez agréable pour voir les différences de fonctions d'une manière interactive rapide.Accélérer Python
Cython : cython est le moyen le plus rapide de prendre quelques fonctions en python et d'obtenir un code plus rapide. Vous pouvez décorer la fonction avec la variante cython de python et elle génère du code c. Ceci est très maintenable et peut également être lié à d'autres codes manuscrits en c / c ++ / fortran assez facilement. C'est de loin l'outil préféré aujourd'hui.
ctypes : ctypes vous permettra d'écrire vos fonctions en c puis de les envelopper rapidement avec sa décoration simple du code. Il gère toute la douleur du casting de PyObjects et de la gestion du gil pour appeler la fonction c.
D'autres approches existent pour écrire votre code en C mais elles sont toutes un peu plus pour prendre une bibliothèque C / C ++ et l'envelopper en Python.
Approches Python uniquement
Si vous souhaitez rester principalement dans Python, mon conseil est de déterminer quelles données vous utilisez et de choisir les types de données appropriés pour implémenter vos algorithmes. D'après mon expérience, vous obtiendrez généralement beaucoup plus loin en optimisant vos structures de données, puis tout hack c de bas niveau. Par exemple:
numpy : un tableau contingent très rapide pour les opérations stridées de tableaux
numexpr : un optimiseur d'expression de tableau numpy. Il permet des expressions de tableau numpy multithreading et supprime également les nombreuses marques temporaires de numpy en raison des restrictions de l'interpréteur Python.
blist : une implémentation b-tree d'une liste, très rapide pour l'insertion, l'indexation et le déplacement des nœuds internes d'une liste
pandas : trames de données (ou tableaux) analyses très rapides sur les tableaux.
pytables : tableaux hiérarchiques structurés rapides (comme hdf5), particulièrement adaptés aux calculs hors du noyau et aux requêtes sur des données volumineuses.
la source
Tout d'abord, si une implémentation C ou Fortran est disponible (fonction MATLAB MEX?), Pourquoi n'écrivez-vous pas un wrapper Python?
Si vous voulez que votre propre implémentation ne soit pas seulement un wrapper, je vous suggère fortement d'utiliser le module numpy pour des choses d'algèbre linéaire. Assurez-vous qu'il est lié à un blas optimisé (comme ATLAS, GOTOblas, uBLAS, Intel MKL, ...). Et utilisez Cython ou weave. Lisez cet article sur Python sur les performances pour une bonne introduction et une référence. Les différentes implémentations de cet article sont disponibles en téléchargement ici avec l'aimable autorisation de Travis Oliphant (Numpy-guru).
Bonne chance.
la source
scipy.weave
encore utilisé et développé? Il semble que l'article Performance Python montre qu'il pourrait être rapide à utiliser et donne une assez bonne amélioration de la vitesse, mais je l'ai rarement vu mentionné en dehors de cet article.En gros, je suis d'accord avec les autres réponses. Les meilleures options pour un
python
code numérique rapide sontnumpy
python
programme puisse l'appeler directementMais si vous voulez programmer l'intégralité de l'algorithme à partir de zéro (je cite: "Je n'utilise que du Python brut"), vous voudrez peut-être envisager http://pypy.org/ une implémentation JIT (Just In Time) de
python
. Je n'ai pas pu l'utiliser pour mon projet (car cela dépendnumpy
et lespypy
gars travaillent correctement pour le supporter) mais les benchmarks sont assez impressionnants ( http://speed.pypy.org/ )la source
Certains des liens ci-dessus sont obsolètes, regardez donc ici:
http://wiki.scipy.org/PerformanceTips
http://wiki.scipy.org/PerformancePython
Quelques idées:
Numpy, Numba, Cython, Numexpr, Theano, Tensorflow, f2py, API CPython C, pypy, cffi, Pythran, Nuitka, swig, boost.python
la source