Welche Tools oder Ansätze stehen zur Verfügung, um den in Python geschriebenen Code zu beschleunigen?

29

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.

Geoff Oxberry
quelle
Auf diese Frage habe ich eine pythonspezifische Antwort gegeben: scicomp.stackexchange.com/questions/2429/… Ich denke, die Hinweise und Links dort sind hilfreich für Sie.
AlexE
(h / t an @AlexE, um mich darauf aufmerksam zu machen) Es gibt definitiv Überschneidungen bei dieser Frage: Wie schreibe ich Simulationen, die schneller laufen? , und Was sind einige gute Strategien zur Verbesserung der seriellen Leistung meines Codes? . Eine Art Zusammenführung könnte in Ordnung sein. Ich habe darüber auf Meta gepostet.
Geoff Oxberry
1
Schauen Sie sich neben den guten Antworten auch diesen Link an .
Mike Dunlavey

Antworten:

40

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 : DietimeitFunktion 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.

aterrel
quelle
3
Sie können ctypes auch zum Aufrufen von Fortran-Routinen verwenden.
Matthew Emmett
Apropos Code-Wrapping, was ist mit f2py?
Astrojuanlu
f2py ist ein großartiges Tool und wird von vielen in der Community verwendet. fwrap ist ein neuerer Ersatz, da f2py sein Alter zeigt, aber nicht wirklich vollständig ist.
Aterrel
Vielen Dank! Dies sind die Arten von Ressourcen, nach denen ich gesucht habe. Ich war mir nur einiger von ihnen bewusst und nur nebenbei (oder indem ich sie im Internet ansah). Aron erwähnt immer wieder numexpr. Wie funktioniert das? Würde das zutreffen?
Geoff Oxberry
7

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.

GertVdE
quelle
Dieser Performance Python-Artikel scheint ein bisschen veraltet zu sein, er erwähnt nicht einige der neueren verfügbaren Tools wie numexpr.
Aron Ahmadia
Ich habe in der Tat numexpr übersehen. Es wäre schön, den gleichen Laplace-Benchmark mit numexpr ...
GertVdE
Wird scipy.weavenoch 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.
Ken
@Ken: scipy.weave befindet sich meines Wissens nicht mehr in aktiver Entwicklung. Es wird aus Gründen der Abwärtskompatibilität beibehalten, aber neue Projekte sollten Cython verwenden.
GertVdE
Informationen zu GotoBLAS und NumPy / SciPy finden Sie unter der-schnorz.de/2012/06/optimized-linear-algebra-and-numpyscipy
AlexE 13.06.12
4

Grundsätzlich stimme ich den anderen Antworten zu. Die besten Optionen für schnellen numerischen pythonCode sind

  • Verwenden Sie spezielle Bibliotheken wie numpy
  • Wickeln Sie Ihren vorhandenen Code so ein, dass Ihr pythonProgramm ihn direkt aufrufen kann

Aber 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ängt numpyund die pypyJungs ständig daran arbeiten, das zu unterstützen), aber die Benchmarks sind ziemlich beeindruckend ( http://speed.pypy.org/ )

bgschaid
quelle