Java Language Ein evidenzbasierter Ansatz für die Java-Leistungsoptimierung


Beispiel

Donald Knuth wird oft so zitiert:

„Programmierer verschwenden enorme Mengen an Zeit darüber nachzudenken, oder sich Gedanken über die Geschwindigkeit von nicht kritischen Teile ihrer Programme, und diese Versuche der Effizienz haben tatsächlich eine starke negative Auswirkungen , wenn die Fehlersuche und Wartung berücksichtigt werden. Wir sollten über kleine Effizienz vergessen, sagen In 97% der Fälle : vorzeitige Optimierung ist die Wurzel allen Übels. Dennoch sollten wir unsere Chancen in den kritischen 3% nicht aufgeben. "

Quelle

In Anbetracht dieses weisen Ratschlags wird hier das empfohlene Verfahren zur Optimierung von Programmen empfohlen:

  1. Entwerfen und codieren Sie zunächst Ihr Programm oder Ihre Bibliothek mit einem Fokus auf Einfachheit und Korrektheit. Um zu beginnen, geben Sie sich nicht viel Mühe für die Leistung.

  2. Bringen Sie es in einen funktionierenden Zustand und entwickeln Sie (idealerweise) Komponententests für die wichtigsten Teile der Codebase.

  3. Entwickeln Sie einen Performance-Benchmark auf Anwendungsebene. Der Benchmark sollte die leistungskritischen Aspekte Ihrer Anwendung abdecken und eine Reihe von Aufgaben ausführen, die typisch für die Verwendung der Anwendung in der Produktion sind.

  4. Messen Sie die Leistung.

  5. Vergleichen Sie die gemessene Leistung mit Ihren Kriterien, wie schnell die Anwendung sein muss. (Vermeiden Sie unrealistische, unerreichbare oder nicht quantifizierbare Kriterien wie "so schnell wie möglich".)

  6. Wenn Sie die Kriterien erfüllt haben, STOPPEN. Deine Arbeit ist erledigt. (Jede weitere Anstrengung ist wahrscheinlich Zeitverschwendung.)

  7. Profilieren Sie die Anwendung, während Ihr Leistungsbenchmark ausgeführt wird.

  8. Überprüfen Sie die Ergebnisse der Profilerstellung und wählen Sie die größten (nicht optimierten) "Leistungs-Hotspots" aus. Dies sind Abschnitte des Codes, in denen die Anwendung die meiste Zeit zu verbringen scheint.

  9. Analysieren Sie den Hotspot-Codeabschnitt, um herauszufinden, warum er einen Engpass darstellt, und überlegen Sie, wie er schneller werden kann.

  10. Implementieren Sie dies als vorgeschlagene Codeänderung, testen und debuggen.

  11. Führen Sie den Benchmark erneut aus, um zu sehen, ob die Codeänderung die Leistung verbessert hat:

    • Wenn ja, kehren Sie zu Schritt 4 zurück.
    • Wenn nein, brechen Sie die Änderung ab und kehren Sie zu Schritt 9 zurück. Wenn Sie keine Fortschritte erzielen, wählen Sie einen anderen Hotspot aus.

Schließlich werden Sie zu einem Punkt gelangen, an dem die Anwendung entweder schnell genug ist oder Sie alle wichtigen Hotspots berücksichtigt haben. An diesem Punkt müssen Sie diesen Ansatz stoppen. Wenn ein Codeabschnitt etwa 1% der Gesamtzeit beansprucht, führt eine Verbesserung um 50% dazu, dass die Anwendung insgesamt nur um 0,5% schneller wird.

Natürlich gibt es einen Punkt, bei dem die Optimierung von Hotspots eine Verschwendung von Aufwand bedeutet. Wenn Sie an diesen Punkt gelangen, müssen Sie radikaler vorgehen. Zum Beispiel:

  • Sehen Sie sich die algorithmische Komplexität Ihrer Kernalgorithmen an.
  • Wenn die Anwendung viel Zeit für die Garbage Collection aufbringt, suchen Sie nach Wegen, um die Objekterstellungsrate zu reduzieren.
  • Wenn wichtige Teile der Anwendung CPU-intensiv und Single-Threaded sind, sollten Sie nach Möglichkeiten für Parallelität suchen.
  • Wenn die Anwendung bereits mehrere Threads umfasst, suchen Sie nach Parallelitätsengpässen.

Verlassen Sie sich jedoch, wo immer möglich, auf Werkzeuge und Messungen und nicht auf Instinkt, um Ihre Optimierungsanstrengungen zu steuern.