Hintergrund: Ich denke, ich möchte vielleicht einen Code portieren, der Matrix-Exponentialvektor-Produkte mit einer Krylov-Subspace-Methode von MATLAB nach Python berechnet. (Insbesondere die expmvp- Funktion von Jitse Niesen , bei der ein in diesem Artikel beschriebener Algorithmus verwendet wird .) Ich weiß jedoch, dass ich nur Funktionen aus Modulen verwende, die aus kompilierten Bibliotheken stammen (dh ich verwende nur unformatiertes Python und nicht viele integrierte Python-Funktionen). in funktionen), dann könnte es recht langsam werden.
Frage: Welche Tools oder Ansätze stehen zur Verfügung, um den in Python geschriebenen Code zu beschleunigen und die Leistung zu verbessern? Insbesondere interessiere ich mich für Tools, die den Prozess so weit wie möglich automatisieren, aber auch allgemeine Ansätze sind willkommen.
Hinweis: Ich habe eine ältere Version des Jitse-Algorithmus und habe sie eine Weile nicht mehr verwendet. Es könnte sehr einfach sein, diesen Code schnell zu erstellen, aber ich hatte das Gefühl, dass er ein gutes konkretes Beispiel sein würde, und er hängt mit meiner eigenen Forschung zusammen. Die Debatte über meinen Ansatz zur Implementierung dieses bestimmten Algorithmus in Python ist eine andere Frage.
quelle
Antworten:
Ich werde meine Antwort in drei Teile aufteilen. Profilerstellung, Beschleunigung des Python-Codes über c und Beschleunigung des Python-Codes über python. Ich bin der Meinung, dass Python einige der besten Tools bietet, um die Leistung Ihres Codes zu überprüfen und die tatsächlichen Engpässe zu ermitteln. Das Beschleunigen von Code ohne Profilerstellung ähnelt dem Versuch, ein Reh mit einem Uzi zu töten.
Wenn Sie sich wirklich nur für Produkte von mat-vec interessieren, empfehle ich scipy.sparse .
Python-Tools für die Profilerstellung
Profile- und cProfile-Module : Mit diesen Modulen erhalten Sie Ihre Standard-Laufzeitanalyse und Ihren Funktionsaufruf-Stack. Es ist sehr schön, ihre Statistiken zu speichern und mit dem pstats-Modul können Sie die Daten auf verschiedene Arten anzeigen.
kernprof : Dieses Tool stellt viele Routinen zusammen, um Dinge wie zeilenweise Code-Timing durchzuführen
memory_profiler : Dieses Tool erstellt einen zeilenweisen Speicher- Footprint Ihres Codes.
IPython-Timer : Die
timeit
Funktion ist sehr hilfreich, um die Funktionsunterschiede schnell und interaktiv zu erkennen.Python beschleunigen
Cython : Cython ist der schnellste Weg, um einige Funktionen in Python zu übernehmen und schnelleren Code zu erhalten. Sie können die Funktion mit der Cython-Variante von Python dekorieren und sie generiert C-Code. Dies ist sehr wichtig und kann auch leicht mit anderem Code in c / c ++ / fortran verknüpft werden. Es ist bei weitem das bevorzugte Werkzeug heute.
ctypes : Mit ctypes können Sie Ihre Funktionen in c schreiben und sie dann schnell mit der einfachen Dekoration des Codes umbrechen. Es behandelt alle Probleme, die mit dem Casting von PyObjects und der Verwaltung des Gil-Befehls zum Aufrufen der c-Funktion verbunden sind.
Es gibt andere Ansätze, um Ihren Code in C zu schreiben, aber alle sind etwas mehr, um eine C / C ++ - Bibliothek zu nehmen und in Python zu verpacken.
Python-only-Ansätze
Wenn Sie hauptsächlich in Python bleiben möchten, ist mein Rat, herauszufinden, welche Daten Sie verwenden, und die richtigen Datentypen für die Implementierung Ihrer Algorithmen auszuwählen. Ich habe die Erfahrung gemacht, dass Sie in der Regel viel weiter kommen, wenn Sie Ihre Datenstrukturen optimieren, als wenn Sie einen Hack auf niedriger Ebene ausführen. Beispielsweise:
numpy : Ein fortlaufendes Array, das für schrittweise Operationen von Arrays sehr schnell ist
numexpr : ein Optimierer für numpy-Array-Ausdrücke. Es ermöglicht Multithreading-Numpy-Array-Ausdrücke und beseitigt die zahlreichen temporären Numpy-Ausdrücke aufgrund von Einschränkungen des Python-Interpreters.
Blist : Eine B-Tree-Implementierung einer Liste, die sich sehr schnell zum Einfügen, Indizieren und Verschieben der internen Knoten einer Liste eignet
Pandas : Datenrahmen (oder Tabellen) sehr schnelle Analysen auf den Arrays.
pytables : Schnell strukturierte hierarchische Tabellen (wie hdf5), besonders geeignet für Berechnungen außerhalb des Kerns und Abfragen zu großen Datenmengen.
quelle
Wenn eine C- oder Fortran-Implementierung verfügbar ist (MATLAB MEX-Funktion?), Warum schreiben Sie keinen Python-Wrapper?
Wenn Sie für Ihre eigene Implementierung nicht nur einen Wrapper benötigen, empfehle ich dringend, das Modul numpy für lineare Algebra zu verwenden. Stellen Sie sicher, dass es mit einem optimierten Blas verbunden ist (wie ATLAS, GOTOblas, uBLAS, Intel MKL, ...). Und Cython verwenden oder weben. In diesem Performance Python- Artikel finden Sie eine gute Einführung und einen Benchmark. Die verschiedenen Implementierungen in diesem Artikel können hier mit freundlicher Genehmigung von Travis Oliphant (Numpy-Guru) heruntergeladen werden .
Viel Glück.
quelle
scipy.weave
noch verwendet und weiterentwickelt? Es scheint, dass der Performance Python-Artikel zeigt, dass es schnell zu bedienen ist und eine ziemlich gute Verbesserung der Geschwindigkeit bietet, aber ich habe es nur selten außerhalb dieses Artikels erwähnt.Grundsätzlich stimme ich den anderen Antworten zu. Die besten Optionen für schnellen numerischen
python
Code sindnumpy
python
Programm ihn direkt aufrufen kannAber wenn Sie den gesamten Algorithmus von Grund auf neu programmieren möchten (ich zitiere: "Ich verwende nur Python"), sollten Sie http://pypy.org/ eine JIT (Just In Time) -Implementierung von in Betracht ziehen
python
. Ich war nicht in der Lage, es für mein Projekt zu verwenden (weil das davon abhängtnumpy
und diepypy
Jungs ständig daran arbeiten, das zu unterstützen), aber die Benchmarks sind ziemlich beeindruckend ( http://speed.pypy.org/ )quelle
Einige der oben genannten Links sind veraltet. Schauen Sie daher hier:
http://wiki.scipy.org/PerformanceTips
http://wiki.scipy.org/PerformancePython
Einige Ideen:
Numpy, Numba, Cython, Numexpr, Theano, Tensorflow, f2py, CPython-C-API, pypy, cffi, Pythran, Nuitka, swig, boost.python
quelle