Die Beispiele in diesem Artikel fassen Techniken zur Java-Leistungsoptimierung zusammen. Teilen Sie es als Referenz mit allen. Die spezifische Analyse lautet wie folgt:
Hier verweisen wir auf einige Bücher und Netzwerkressourcen, die für die meisten Java-Anwendungen geeignet sind.
Bei JAVA-Programmen liegen die meisten Ursachen für Leistungsprobleme nicht in der JAVA-Sprache, sondern im Programm selbst. Die Entwicklung guter Programmiergewohnheiten ist sehr wichtig und kann die Programmleistung erheblich verbessern.
1. Versuchen Sie, den letzten Modifikator zu verwenden.
Klassen mit dem finalen Modifikator werden nicht abgeleitet. In der JAVA-Kern-API gibt es viele Beispiele für die Anwendung von final, beispielsweise java.lang.String. Durch die Angabe von final für die String-Klasse wird verhindert, dass Benutzer die Methode length() überschreiben. Wenn eine Klasse außerdem final ist, sind alle Methoden der Klasse final. Der Java-Compiler sucht nach Möglichkeiten, alle endgültigen Methoden zu integrieren (dies hängt von der jeweiligen Compiler-Implementierung ab). Dadurch kann die Leistung um durchschnittlich 50 % verbessert werden.
2. Versuchen Sie, Objekte wiederzuverwenden.
Insbesondere bei der Verwendung von String-Objekten sollte stattdessen StringBuffer verwendet werden, wenn eine String-Verkettung auftritt, da das System nicht nur Zeit für die Generierung von Objekten aufwenden muss, sondern in Zukunft möglicherweise auch Zeit für die Müllsammlung und -verarbeitung dieser Objekte aufwenden muss. Daher hat die Generierung zu vieler Objekte große Auswirkungen auf die Leistung des Programms.
3. Versuchen Sie, lokale Variablen zu verwenden.
Die beim Aufruf der Methode übergebenen Parameter und die beim Aufruf erstellten temporären Variablen werden im Stapel (Stack) gespeichert, was schneller ist. Andere Variablen wie statische Variablen, Instanzvariablen usw. werden im Heap erstellt und sind langsamer.
4. Initialisieren Sie Variablen nicht wiederholt.
Standardmäßig initialisiert Java beim Aufrufen des Konstruktors einer Klasse Variablen auf bestimmte Werte, alle Objekte werden auf Null gesetzt, Ganzzahlvariablen werden auf 0 gesetzt, Float- und Double-Variablen werden auf 0,0 gesetzt und logische Werte werden auf gesetzt FALSCH. Dies sollte insbesondere dann beachtet werden, wenn eine Klasse von einer anderen Klasse abgeleitet ist, da beim Erstellen eines Objekts mit dem Schlüsselwort new automatisch alle Konstruktoren in der Konstruktorkette aufgerufen werden.
Hier gibt es einen Hinweis: Wenn Sie den Anfangswert für eine Mitgliedsvariable festlegen, aber andere Methoden aufrufen müssen, ist es am besten, ihn in eine Methode wie initXXX() einzufügen, da der direkte Aufruf einer Methode zum Zuweisen eines Werts zu einer Null führen kann Zeigerausnahme, da die Klasse nicht initialisiert wurde. public int state = this.getState();
5. Bei der Entwicklung von Java + Oracle-Anwendungssystemen sollte die in Java eingebettete SQL-Sprache so weit wie möglich in Großbuchstaben geschrieben werden, um die Analyselast des Oracle-Parsers zu verringern.
6. Führen Sie während des Java-Programmierungsprozesses Datenbankverbindungen und E/A-Stream-Vorgänge durch. Schließen Sie sie nach der Verwendung rechtzeitig, um Ressourcen freizugeben. Weil Operationen an diesen großen Objekten einen hohen Systemaufwand verursachen.
7. Übermäßiges Erstellen von Objekten verbraucht viel Systemspeicher und kann in schweren Fällen zu Speicherverlusten führen. Daher ist es von großer Bedeutung, die rechtzeitige Wiederverwendung abgelaufener Objekte sicherzustellen.
Der GC der JVM ist nicht sehr intelligent, daher wird empfohlen, ihn nach der Verwendung des Objekts manuell auf Null zu setzen.
8. Versuchen Sie bei Verwendung des Synchronisierungsmechanismus, die Methodensynchronisierung anstelle der Codeblocksynchronisierung zu verwenden.
9. Minimieren Sie die Doppelzählung von Variablen.
Zum Beispiel
for(int i=0;i<list.size();i++)
sollte geändert werden
for(int i=0,len=list.size();i<len;i++)
10. Übernehmen Sie die Strategie, nur dann etwas zu schaffen, wenn Sie es brauchen.
Zum Beispiel:
String str="abc";if(i==1){ list.add(str);}
Sollte geändert werden in:
if(i==1){String str="abc"; list.add(str);}
11. Verwenden Sie Ausnahmen mit Vorsicht, da Ausnahmen die Leistung beeinträchtigen.
Durch das Auslösen einer Ausnahme wird zunächst ein neues Objekt erstellt. Der Konstruktor der Throwable-Schnittstelle ruft eine lokale Methode namens fillInStackTrace() auf. Die Methode fillInStackTrace() überprüft den Stapel und sammelt Informationen zur Anrufverfolgung. Immer wenn eine Ausnahme ausgelöst wird, muss die VM den Aufrufstapel anpassen, da während der Verarbeitung ein neues Objekt erstellt wird.
Ausnahmen sollten nur zur Fehlerbehandlung und nicht zur Steuerung des Programmablaufs verwendet werden.
12. Verwenden Sie keine Try/Catch-Anweisungen in Schleifen. Try/Catch sollte auf der äußersten Ebene der Schleife platziert werden.
Error ist eine Klasse zum Abrufen von Systemfehlern oder Fehlern virtueller Maschinen. Es können nicht alle Fehlerausnahmen abgerufen werden. Wenn die virtuelle Maschine eine Fehlerausnahme meldet, müssen Sie sie mit „Error“ abrufen.
13. Durch Festlegen der anfänglichen Kapazität von StringBuffer über seinen Konstruktor kann die Leistung erheblich verbessert werden.
Die Standardkapazität von StringBuffer beträgt 16. Wenn die Kapazität von StringBuffer die maximale Kapazität erreicht, erhöht es seine Kapazität auf das Zweifache + 2 der aktuellen Kapazität, was 2 * n + 2 entspricht. Immer wenn StringBuffer seine maximale Kapazität erreicht, muss er ein neues Array von Objekten erstellen und dann das alte Array von Objekten kopieren, was viel Zeit verschwendet. Daher ist es notwendig, einen angemessenen anfänglichen Kapazitätswert für StringBuffer festzulegen!
14. Verwenden Sie java.util.Vector sinnvoll.
Vector ähnelt StringBuffer. Bei jeder Kapazitätserweiterung müssen alle vorhandenen Elemente dem neuen Speicherplatz zugewiesen werden. Die Standardspeicherkapazität von Vector beträgt 10 Elemente und die Kapazität wird verdoppelt.
vector.add(index,obj) Diese Methode kann das Element obj an der Indexposition einfügen, der Index und die nachfolgenden Elemente müssen jedoch um eine Position nach unten verschoben werden (ihren Index um 1 erhöhen). Schlecht für die Leistung, es sei denn, es ist notwendig.
Die gleichen Regeln gelten für die Methode „remove(int index)“, die das Element an der angegebenen Position in diesem Vektor entfernt. Verschieben Sie alle nachfolgenden Elemente nach links (verringern Sie ihren Index um 1). Gibt die entfernten Elemente aus diesem Vektor zurück. Daher ist das Löschen des letzten Elements des Vektors viel kostengünstiger als das Löschen des ersten Elements. Am besten verwenden Sie die Methode „removeAllElements()“, um alle Elemente zu entfernen.
Wenn Sie ein Element im Vektor löschen möchten, können Sie vector.remove(obj) verwenden. Sie müssen die Elementposition nicht selbst abrufen und dann löschen, z. B. int index = indexOf(obj); Index);
15. Verwenden Sie beim Kopieren großer Datenmengen System.arraycopy();
16. Code-Refactoring zur Verbesserung der Code-Lesbarkeit.
17. Erstellen Sie eine Instanz eines Objekts, ohne das Schlüsselwort new zu verwenden.
Wenn Sie eine Instanz einer Klasse mit dem Schlüsselwort new erstellen, werden alle Konstruktoren in der Konstruktorkette automatisch aufgerufen. Aber wenn ein Objekt die Cloneable-Schnittstelle implementiert, können wir ihre clone()-Methode aufrufen. Die Methode clone() ruft keine Klassenkonstruktoren auf.
Das Folgende ist eine typische Implementierung des Factory-Musters.
public static Credit getNewCredit(){ return new Credit();} Der verbesserte Code verwendet die Methode clone(), private static Credit BaseCredit = new Credit(); ;}
18. Wenn die Verschiebung zur Multiplikation und Division verwendet werden kann, sollte die Verschiebung so oft wie möglich verwendet werden. Es ist jedoch am besten, Kommentare hinzuzufügen, da die Verschiebungsoperation nicht intuitiv und schwer zu verstehen ist.
19. Deklarieren Sie das Array nicht als: public static final.
20.HaspMap-Durchquerung.
Map<String, String[]> paraMap = new HashMap<String, String[]>();for( Entry<String, String[]> enter : paraMap.entrySet() ){ String appFieldDefId = enter.getKey(); String[] Werte = Eintrag.getValue();}
Verwenden Sie den Hash-Wert, um den entsprechenden Eintrag zum Vergleich abzurufen und das Ergebnis zu erhalten. Rufen Sie nach Erhalt des Eintragswerts direkt den Schlüssel und den Wert ab.
21. Die Verwendung von Array (Array) und ArrayList.
Das Array-Array ist am effizientesten, seine Kapazität ist jedoch fest und kann nicht dynamisch geändert werden. Die Kapazität von ArrayList kann dynamisch erhöht werden, die Effizienz geht jedoch verloren.
22. Einzelne Threads sollten versuchen, HashMap und ArrayList zu verwenden. Es wird nicht empfohlen, HashTable und Vector zu verwenden. Sie verwenden einen Synchronisierungsmechanismus und verringern die Leistung.
23. Der Unterschied zwischen StringBuffer und StringBuilder ist: java.lang.StringBuffer ist eine threadsichere variable Zeichenfolge. Ein String-Puffer ähnlich wie String, der jedoch nicht geändert werden kann. StringBuilder Die StringBuilder-Klasse sollte im Allgemeinen dieser Klasse vorgezogen werden, da sie dieselben Vorgänge unterstützt, aber schneller ist, da sie keine Synchronisierung durchführt. Um eine bessere Leistung zu erzielen, sollten Sie versuchen, ihre Kapazität beim Erstellen von StringBuffer oder StringBuilder anzugeben. Dies ist natürlich nicht erforderlich, wenn die Länge 16 Zeichen nicht überschreitet.
Unter den gleichen Umständen kann die Verwendung von StringBuilder nur eine Leistungsverbesserung von 10 bis 15 % gegenüber der Verwendung von StringBuffer erzielen, es besteht jedoch das Risiko einer Multithreading-Unsicherheit. Nach umfassender Überlegung wird die Verwendung von StringBuffer empfohlen.
24. Versuchen Sie, grundlegende Datentypen anstelle von Objekten zu verwenden.
25. Verwenden Sie einfache numerische Berechnungen anstelle komplexer Funktionsberechnungen , z. B. das Nachschlagen von Tabellen zur Lösung trigonometrischer Funktionsprobleme.
26. Die Verwendung konkreter Analogien ist effizienter als die Verwendung von Schnittstellen, allerdings ist die strukturelle Flexibilität geringer, aber moderne IDEs können dieses Problem lösen.
27. Erwägen Sie die Verwendung statischer Methoden
Wenn Sie nicht auf die Außenseite des Objekts zugreifen müssen, machen Sie Ihre Methode statisch. Der Aufruf erfolgt schneller, da keine virtuelle Funktionsleittabelle erforderlich ist. Diese Kollegin ist ebenfalls eine gute Praxis, da sie Ihnen erklärt, wie Sie die Art der Methode unterscheiden können. Der Aufruf dieser Methode ändert den Status des Objekts nicht.
28. Die Verwendung intrinsischer GET- und SET-Methoden sollte so weit wie möglich vermieden werden.
Bei der Android-Programmierung verursacht der Aufruf virtueller Methoden hohe Kosten, die teurer sind als die Abfrage von Instanzattributen. Bei der Auslagerung von Aufrufen sollten wir nur Get- und Set-Methoden verwenden, bei internen Aufrufen sollten wir sie jedoch direkt aufrufen.
29. Vermeiden Sie die Verwendung von Aufzählungen und Gleitkommazahlen.
30. Ein zweidimensionales Array benötigt mehr Speicherplatz als ein eindimensionales Array, etwa das Zehnfache der Berechnung.
31. Die SQLite-Datenbank liest alle Daten der gesamten Tabelle sehr schnell, aber bedingte Abfragen dauern 30-50 MS. Dabei sollte jeder darauf achten, sie so wenig wie möglich zu verwenden, insbesondere bei verschachtelten Suchen!
Ich hoffe, dass dieser Artikel für die Java-Programmierung aller hilfreich sein wird.