Suche…


Allgemeiner Ansatz

Das Internet enthält zahlreiche Tipps zur Leistungsverbesserung von Java-Programmen. Vielleicht ist der wichtigste Tipp das Bewusstsein. Das bedeutet:

  • Mögliche Leistungsprobleme und Engpässe erkennen.
  • Verwenden Sie Analyse- und Testwerkzeuge.
  • Kennen Sie bewährte Praktiken und schlechte Praktiken.

Der erste Punkt sollte während der Entwurfsphase gemacht werden, wenn über ein neues System oder Modul gesprochen wird. Wenn Sie über Legacy-Code sprechen, kommen Analyse- und Test-Tools zum Tragen. Das grundlegendste Werkzeug für die Analyse Ihrer JVM-Leistung ist JVisualVM, das im JDK enthalten ist.

Der dritte Punkt ist vor allem über Erfahrung und umfangreiche Forschung und natürlich roh Tipps , die auf dieser Seite und andere, wie Show wird dies .

Anzahl der Saiten reduzieren

In Java ist es zu "einfach", viele nicht benötigte String-Instanzen zu erstellen. Dies und andere Gründe können dazu führen, dass Ihr Programm viele Strings hat, die der GC gerade bereinigt.

Einige Möglichkeiten, wie Sie String-Instanzen erstellen können:

myString += "foo";

Oder noch schlimmer, in einer Schleife oder Rekursion:

for (int i = 0; i < N; i++) {
    myString += "foo" + i;
}

Das Problem ist, dass jedes + einen neuen String erstellt (normalerweise, da neue Compiler einige Fälle optimieren). Eine mögliche Optimierung kann mit StringBuilder oder StringBuffer :

StringBuffer sb = new StringBuffer(myString);
for (int i = 0; i < N; i++) {
    sb.append("foo").append(i);
}
myString = sb.toString();

Wenn Sie häufig lange Zeichenfolgen erstellen (z. B. SQLs), verwenden Sie eine Zeichenfolgenerstellungs-API.

Andere Dinge zu beachten:

  • Reduzieren Sie die Verwendung von replace , substring usw.
  • Vermeiden Sie String.toArray() , insbesondere in häufig aufgerufenem Code.
  • Protokollausdrucke, die zum Filtern bestimmt sind (z. B. aufgrund des Protokollierungsniveaus), sollten nicht erstellt werden (Protokollierungsgrad sollte vorab geprüft werden).
  • Verwenden Sie bei Bedarf Bibliotheken wie diese .
  • StringBuilder ist besser, wenn die Variable nicht gemeinsam genutzt wird (über Threads hinweg).

Ein evidenzbasierter Ansatz für die Java-Leistungsoptimierung

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.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow