Tutorials zur Optimierung nicht-trivialer Python-Anwendungen mit C-Erweiterungen oder Cython

Lesezeit: 6 Minuten

Benutzer-Avatar
Gotgene

Die Python-Community hat hilfreiches Referenzmaterial veröffentlicht, das zeigt, wie Python-Code profiliert wird, und die technischen Details von Python-Erweiterungen in C oder in Cython. Ich suche noch nach Tutorials, die allerdings für nicht-triviale Python-Programme folgendes zeigen:

  1. So identifizieren Sie die Hotspots, die von der Optimierung durch Konvertierung in eine C-Erweiterung profitieren
  2. Genauso wichtig ist, wie man die Hotspots identifiziert, die das werden nicht profitieren von der Umstellung auf eine C-Erweiterung
  3. Schließlich, wie man die entsprechende Konvertierung von Python nach C durchführt, entweder mit der Python C-API oder (vielleicht sogar bevorzugt) mit Cython.

Ein gutes Tutorial würde dem Leser eine Methodik vermitteln, wie er das Optimierungsproblem lösen kann, indem er ein vollständiges Beispiel durcharbeitet. Ich hatte keinen Erfolg, eine solche Ressource zu finden.

Kennst du (oder hast du geschrieben) ein solches Tutorial?

Zur Klarstellung, ich bin nicht an Tutorials interessiert, die abdecken nur folgende:

  • Verwenden von (c)Profile zum Profilieren von Python-Code zum Messen von Laufzeiten
  • Verwenden von Tools zum Untersuchen von Profilen (ich empfehle LaufSchlangeLauf)
  • Optimierung durch Auswahl geeigneterer Algorithmen oder Python-Konstrukte (z. B. Sets für Mitgliedschaftstests anstelle von Listen); Das Tutorial sollte davon ausgehen, dass der Algorithmus und der Python-Code bereits optimal sind, und wir sind an einem Punkt angelangt, an dem eine C-Erweiterung der nächste logische Schritt ist
  • Rekapitulieren der Python-Dokumentation zum Schreiben von C-Erweiterungendas sich bereits hervorragend als Referenz eignet, aber nicht als Ressource zum Zeigen, wann und wie Sie von Python zu C wechseln.

Die Punkte 1 und 2 sind nur grundlegende Faustregeln für die Optimierung. Ich wäre sehr erstaunt, wenn es irgendwo die Art von Tutorials gäbe, nach denen Sie suchen. Vielleicht haben Sie deshalb noch keine gefunden. Meine kurze Liste:

  • Regel Nummer eins der Optimierung ist nicht.
  • Regel Nummer zwei messen
  • Regel Nummer drei den limitierenden Faktor identifizieren (Wenn es IO- oder datenbankgebunden ist, ist möglicherweise sowieso keine Optimierung erreichbar).
  • Regel Nummer vier ist denken, Verwenden Sie bessere Algorithmen und Datenstrukturen
  • Über einen Sprachwechsel nachzudenken, steht ganz weit unten auf der Liste…

Beginnen Sie einfach mit der Profilerstellung Ihres Python-Codes mit üblichen Python-Tools. Finden Sie heraus, wo Ihr Code optimiert werden muss. Versuchen Sie dann, es mit Python zu optimieren. Wenn es immer noch zu langsam ist, versuchen Sie zu verstehen, warum. Wenn es IO-gebunden ist, ist es unwahrscheinlich, dass ein C-Programm besser wäre. Wenn das Problem vom Algorithmus herrührt, ist es auch unwahrscheinlich, dass C besser abschneidet. Wirklich die “guten” Fälle, in denen C helfen könnte, sind ziemlich selten, die Laufzeit sollte nicht zu weit von dem entfernt sein, was Sie wollen (wie eine 2 von 3-fache Beschleunigung). Die Datenstruktur ist einfach und würde von einer Darstellung auf niedriger Ebene profitieren, und Sie wirklich, brauche wirklich diese Beschleunigung. In den meisten anderen Fällen ist die Verwendung von C anstelle von Python eine unbefriedigende Aufgabe.

Wirklich, es ist ziemlich selten, dass der Aufruf von C-Code von Python aus mit der Leistung als primärem Ziel durchgeführt wird. Häufiger besteht das Ziel darin, Python mit vorhandenem C-Code zu verbinden.

Und wie ein anderer anderer Poster sagte, wären Sie wahrscheinlich besser beraten, Cython zu verwenden.

Wenn Sie dennoch ein C-Modul für Python schreiben möchten, steht alles Notwendige in der amtliche Dokumentation.

  • Ich würde hinzufügen, dass Sie SWIG oder Boost::Python für bestimmte Aufgaben benötigen.

    – Jake Kurzer

    22. Dezember 2010 um 1:13 Uhr

  • +1 für Algorithmen vor Sprachen. Und um zu überlegen, wo C glänzt – Manipulation einfacher Datenstrukturen auf niedriger Ebene in engen Schleifen

    – tobyodavies

    22. Dezember 2010 um 1:38 Uhr

O’Reilly hat ein Tutorial (soweit ich das beurteilen kann, frei verfügbar, ich konnte das ganze Ding lesen), das veranschaulicht, wie man ein echtes Projekt profiliert (sie verwenden ein EDI-Parsing-Projekt als Thema für die Profilerstellung) und Hotspots identifiziert. Es gibt nicht allzu viele Details zum Schreiben der C-Erweiterung, die den Engpass im O’Reilly-Artikel beheben wird. Es deckt jedoch die ersten beiden gewünschten Dinge mit einem nicht trivialen Beispiel ab.

Der Prozess des Schreibens von C-Erweiterungen ist ziemlich gut dokumentiert hier. Der schwierige Teil besteht darin, Wege zu finden, um zu replizieren, was Python-Code in C tut, und das erfordert etwas, das in einem Tutorial schwer zu lehren wäre: Einfallsreichtum, Kenntnisse über Algorithmen, Hardware und Effizienz sowie beträchtliche C-Kenntnisse.

Hoffe das hilft.

  • Generell mag ich die Python-Artikel von Jeremy Jones, aber dieser war eher schwach. Wie Sie darauf hingewiesen haben, wird nur die Profilerstellung und Optimierung des Algorithmus erörtert und nicht der nächste Schritt unternommen, um zu zeigen, wie Sie durch das Schreiben einer Erweiterung optimieren können. Außerdem glaube ich das hotshot Modul ist veraltet, da es in Python 3 aus der Standardbibliothek entfernt wurde; cProfile sollte stattdessen verwendet werden.

    – Gotgene

    16. Dezember 2010 um 18:54 Uhr


Für Punkt 1 und 2 würde ich zum Beispiel einen Python-Profiler verwenden cProfil. Sehen hier für ein schnelles Tutorial.

Wenn Sie ein bereits vorhandenes Python-Programm haben, sollten Sie für Punkt 3 die Verwendung in Betracht ziehen Cython. Anstatt in C neu zu schreiben, können Sie sich natürlich eine algorithmische Verbesserung ausdenken, die die Ausführungsgeschwindigkeit erhöht.

  • Können Sie ein Tutorial empfehlen, das zeigt, wie Sie ein reines Python-Programm optimieren, indem Sie (Teile davon) in Cython neu schreiben?

    – Gotgene

    16. Dezember 2010 um 18:02 Uhr

Benutzer-Avatar
Mike Dunlavey

Ich werde versuchen, Ihre Punkte 1 und 2 und Ihre ersten 3 Aufzählungspunkte anzusprechen, aber nicht der Reihe nach.

Der dritte Aufzählungspunkt besagt “Angenommen, der Algorithmus und der Python-Code sind bereits optimal”. Wenn sich der Code in diesem Zustand befindet und Stack-Samples genommen werden (wie hier beschrieben), zeigen die Samples aus zeitlicher Sicht genau, was das Programm tut, und es scheint nichts zu geben, was ohne Sprachänderung verbessert werden könnte. Da Sie jedoch wissen, wie er seine Zeit verbringt, wissen Sie, welcher Low-Level-Algorithmus (der aus mehr als einer Funktion bestehen könnte, nicht nur aus einem Hotspot) davon profitieren könnte, weniger Zeit in Anspruch zu nehmen, dh durch eine Konvertierung nach C .

In Bezug auf Punkt 1 zeigt diese Methode, welche Teile des Codes von einer Konvertierung in C profitieren und ob es sich um Hotspots handeln kann oder nicht. (Das erste, was mir in den Sinn kommt, ist jede Art von rekursiver Funktion oder Reihe von Funktionen. Oder eine kleine Gruppe von Funktionen, die zusammen einen bestimmten Zweck erfüllen, z. B. ein Bergsteiger.)

Was Punkt 2 betrifft, jeder Code, der nicht auf einem gesunden Prozentsatz von Stack-Samples erscheint, oder der dies tut, aber eindeutig nicht von einer Konvertierung nach C profitiert, wie z. B. I/O.

In Bezug auf den ersten und zweiten Aufzählungspunkt würde ich zustimmen, dass das Messen nicht das primäre Ziel ist, sondern ein Nebenprodukt des Prozesses, den zu optimierenden Code zu finden. Auch die Darstellung solcher Messungen ist nebensächlich.

Ich war in ähnlichen Situationen, außer nicht zwischen Python und C, sondern zwischen C und Hardware.**

Um nur ein Beispiel zu nennen: Wenn die Gesamtlaufzeit 10 Sekunden beträgt und der Algorithmus ungefähr 50 % der Zeit auf dem Stapel ist, dann ist er für ungefähr 5 der 10 Sekunden verantwortlich. Wenn die Konvertierung des Algorithmus in C eine 10-fache Beschleunigung ergeben würde, würden diese 5 Sekunden auf 0,5 Sekunden schrumpfen, sodass die Gesamtzeit auf 5,5 Sekunden schrumpfen würde. (Grob gesagt – es ist wichtiger, die Zeitersparnis zu erreichen, als im Voraus genau zu wissen, wie groß sie sein wird.) Beachten Sie, dass der gesamte Vorgang an dieser Stelle wiederholt werden könnte, und es könnte sinnvoll sein, auch etwas anderes in C umzuwandeln. Sie können diesen Prozess stoppen, wenn Beispiele zeigen, dass der Python-Code das tut, was er gut kann, und der C-Code das tut, was er gut kann.

** zB Fließkomma-Mathematik, Bibliothek vs. Chip oder Grafik, Zeichnen von Text und Polygonen.

1346490cookie-checkTutorials zur Optimierung nicht-trivialer Python-Anwendungen mit C-Erweiterungen oder Cython

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy