31 Stimmen

Wie kann ich mein Perl-Programm beschleunigen?

Es handelt sich eigentlich um zwei Fragen, aber sie sind sich so ähnlich, dass ich sie der Einfachheit halber einfach zusammenfasse:

  • Erstens : Wenn man ein bestehendes Perl-Projekt hat, welche Möglichkeiten gibt es, es über die reine In-Code-Optimierung hinaus zu beschleunigen?

  • Zweitens : Wenn Sie ein Programm von Grund auf in Perl schreiben, welche Möglichkeiten gibt es, die Leistung erheblich zu verbessern?

Zur ersten Frage: Stellen Sie sich vor, Sie haben ein gut geschriebenes Projekt und müssen die Leistung verbessern, aber Sie können durch Refactoring/Optimierung keine große Verbesserung erzielen. Was würden Sie in diesem Fall tun, um das Projekt zu beschleunigen, außer es in etwas wie C neu zu schreiben?

Bitte halten Sie sich von allgemeinen Optimierungstechniken fern, es sei denn, sie sind Perl-spezifisch .

Ich fragte dies über Python und ich dachte mir, es könnte gut sein, dies auch für andere Sprachen zu tun (ich bin besonders neugierig, ob es Konsequenzen für Psycho et pyrex für Perl).

156voto

Andy Lester Punkte 86147

Bitte denken Sie an die Regeln des Optimierungsclubs:

  1. Die erste Regel des Optimierungsclubs ist, dass Sie nicht optimieren.
  2. Die zweite Regel des Optimization Club lautet: Man optimiert nicht, ohne zu messen.
  3. Wenn Ihre Anwendung schneller läuft als das zugrunde liegende Transportprotokoll, ist die Optimierung abgeschlossen.
  4. Ein Faktor nach dem anderen.
  5. Keine Marktroiden, keine Marktroidenzeitpläne.
  6. Die Tests werden so lange fortgesetzt, wie es nötig ist.
  7. Wenn dies Ihr erster Abend im Optimierungsclub ist, müssen Sie einen Testfall schreiben.

Wenn Sie also tatsächlich funktionierenden Code haben, führen Sie Ihr Programm unter Devel::NYTProf .

Finden Sie die Engpässe. Kommen Sie dann wieder hierher und sagen Sie uns, wo sie liegen.

Wenn Sie nicht einen funktionierenden Code haben, müssen Sie ihn erst zum Laufen bringen. Die größte Optimierung, die Sie jemals vornehmen werden, ist der Übergang von nicht funktionierendem zu funktionierendem Code.

7 Stimmen

Vorgeschlagene Änderung: Nach "Also, angenommen..." hinzufügen: "Wenn Sie keinen funktionierenden Code haben, bringen Sie ihn zuerst zum Laufen. Die größte Optimierung, die Sie jemals vornehmen werden, ist der Übergang von nicht funktionierendem zu funktionierendem Code."

2 Stimmen

Rhetorische Frage: Was ist Perl-spezifisch für diese Optimierungstechnik?

0 Stimmen

Wie das Zitat aus dem Fight Club: "Wenn dies deine erste Nacht im Optimization Club ist, musst du einen Testfall schreiben.".

35voto

pjf Punkte 5921

Andy hat bereits erwähnt Devel::NYTProf . Es ist fantastisch. Wirklich, wirklich großartig. Benutze es.

Wenn Sie aus irgendeinem Grund nicht in der Lage sind Devel::NYTProf dann können Sie auf die gute alte Entwickeln::DProf die schon seit langem zum Standardumfang von Perl gehört. Wenn Sie verdadero Funktionen (im mathematischen Sinne), deren Berechnung viel Zeit in Anspruch nimmt (z. B. Fibonacci-Zahlen), dann können Sie feststellen Memoize bietet eine gewisse Geschwindigkeitsverbesserung.

Ein Großteil der schlechten Leistung ist auf ungeeignete Datenstrukturen und Algorithmen zurückzuführen. Ein guter Kurs in Informatik kann hier sehr hilfreich sein. Wenn Sie zwei Möglichkeiten haben, Dinge zu tun, und deren Leistung vergleichen möchten, können Sie die Benchmark Modul kann sich ebenfalls als nützlich erweisen.

Die folgenden Perl-Tipps kann sich auch hier als nützlich erweisen:

Haftungsausschluss: Einige der oben genannten Ressourcen wurden von mir verfasst, so dass ich ihnen gegenüber voreingenommen sein könnte.

32voto

brian d foy Punkte 124323

Es gibt viele Dinge, die Sie verbessern könnten, also müssen Sie zuerst herausfinden, was langsam ist. Andere haben diese Frage bereits beantwortet. Ich spreche darüber ein wenig in Perl beherrschen auch.

Eine unvollständige Liste von Dingen, an die Sie denken sollten, wenn Sie neuen Code schreiben:

  • Profil mit etwas wie Devel::NYTProf um zu sehen, wo Sie die meiste Zeit im Code verbringen. Manchmal ist das überraschend und leicht zu beheben. Perl beherrschen hat viele Ratschläge zu diesem Thema.

  • Perl muss den Quellcode jedes Mal kompilieren, und die Kompilierung kann langsam sein. Es muss alle Dateien finden und so weiter. Siehe, zum Beispiel, "Ein rechtzeitiger Start" von Jean-Louis Leroy, in dem er alles beschleunigt, indem er einfach die Modulpositionen in @INC . Wenn Ihre Anlaufkosten teuer und unvermeidlich sind, könnten Sie auch persistente Perls wie pperl, mod_perl usw. in Betracht ziehen.

  • Sehen Sie sich einige der von Ihnen verwendeten Module an. Haben sie lange Ketten von Abhängigkeiten, nur um einfache Dinge zu tun? Sicher, wir mögen es nicht, wenn etwas neu erfunden wird, aber wenn das Rad, das Sie an Ihrem Auto anbringen wollen, auch drei Boote, fünf Ziegen und einen Cheeseburger enthält, sollten Sie vielleicht Ihr eigenes Rad bauen (oder ein anderes finden).

  • Methodenaufrufe können teuer sein. In der Perl::Critic-Testsuite zum Beispiel sind die Aufrufe an isa verlangsamt die Dinge. Das kann man nicht in allen Fällen vermeiden, aber man sollte es im Hinterkopf behalten. Jemand hatte ein großartiges Zitat, das ungefähr so lautete: "Niemandem macht es etwas aus, einen Faktor 2 aufzugeben; es ist nur schlecht, wenn zehn Leute es tun." :) Perl v5.22 hat einige Leistungsverbesserungen für diesen Fall.

  • Wenn Sie dieselben teuren Methoden immer wieder aufrufen, aber dieselben Antworten erhalten, z. B. Memoize für Sie sein könnte. Es ist ein Proxy für den Methodenaufruf. Wenn es sich wirklich um eine Funktion handelt (d. h. dieselbe Eingabe ergibt dieselbe Ausgabe ohne Seiteneffekte), brauchen Sie sie nicht wiederholt aufzurufen.

  • Module wie zum Beispiel Apache::DBI kann Datenbank-Handles für Sie wiederverwenden, um das teure Öffnen von Datenbankverbindungen zu vermeiden. Es ist wirklich einfacher Code, so dass ein Blick in den Code Ihnen zeigen kann, wie man das macht, auch wenn Sie nicht Apache verwenden.

  • Perl optimiert die Tail-Rekursion nicht für Sie, also kommen Sie nicht von Lisp und denken Sie, dass Sie diese superschnellen rekursiven Algorithmen machen werden. Sie können diese leicht in iterative Lösungen umwandeln (und wir sprechen darüber in Perl für Fortgeschrittene .

  • Sehen Sie sich Ihre Regexe an. Viele Quantifizierer mit offenem Ende (z. B. .* ) kann zu einer Vielzahl von Rückverfolgungen führen. Lesen Sie Jeffrey Freidls Reguläre Ausdrücke beherrschen für alle blutigen Details (und in mehreren Sprachen). Besuchen Sie auch seine Regex-Website .

  • Wissen, wie Ihr Perl kompiliert wird. Brauchen Sie wirklich Threading und DDEBUGGING ? Diese verlangsamen die Fahrt ein wenig. Schauen Sie sich das Dienstprogramm perlbench an, um verschiedene Perl-Binärdateien zu vergleichen.

  • Vergleichen Sie Ihre Anwendung mit verschiedenen Perls. Einige neuere Versionen haben Geschwindigkeitsvorteile, aber auch einige ältere Versionen können für bestimmte Operationen schneller sein. Ich habe keine besonderen Ratschläge, da ich nicht weiß, was Sie tun.

  • Verteilen Sie die Arbeit. Können Sie einige asynchrone Arbeiten in anderen Prozessen oder auf entfernten Computern durchführen? Lassen Sie Ihr Programm an anderen Dingen arbeiten, während jemand anderes einige Teilprobleme löst. Perl hat mehrere asynchrone und lastverschiebende Module. Beachten Sie aber, dass das Gerüst, um diese Dinge gut zu machen, jeglichen Nutzen verlieren könnte.

14voto

tsee Punkte 4970

Ohne große Teile neu schreiben zu müssen, können Sie mit Inline::C um eine einzelne, langsame Subroutine nach C zu konvertieren. Oder verwenden Sie direkt XS. Es ist auch möglich, Unterprogramme mit XS schrittweise zu konvertieren. PPI/PPI::XS tut dies zum Beispiel.

Aber der Wechsel zu einer anderen Sprache ist immer ein letzter Ausweg. Vielleicht sollten Sie einen erfahrenen Perl-Programmierer bitten, sich Ihren Code anzuschauen? Höchstwahrscheinlich würde er eine Besonderheit entdecken, die Ihre Leistung ernsthaft beeinträchtigt. Ansonsten sollten Sie ein Profil Ihres Codes erstellen. Denken Sie daran, dass es kein Patentrezept gibt.

In Bezug auf Psyco und Pyrex: Nein, es gibt keine Entsprechung für Perl.

9voto

leek Punkte 11253

Dies bezieht sich nur zur Hälfte auf Ihre Frage - aber im Interesse der Dokumentation werde ich es hier veröffentlichen.

Eine aktuelle CentOS/Perl Fehlerbehebung hat die Geschwindigkeit unserer Anwendung mehr als verdoppelt. Dies ist ein Muss für jeden, der CentOS Perl einsetzt und die bless/overload-Funktionen verwendet.

0 Stimmen

Oh, gutes Argument. Mehr über den Fehler und ein Testprogramm, um zu sehen, ob er Ihren Code betrifft, finden Sie unter perlbuzz.com/2008/08/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X