Code -Optimierungsdetails
1. Versuchen Sie, festzustellen, dass der endgültige Modifikator der Klasse und Methode. Klassen mit endgültigen Modifikatoren mit endgültigen Modifikatoren können nicht abgeleitet werden. In der Java -Kern -API gibt es viele Beispiele für die endgültige Anwendung, wie Java.lang.String, und die gesamte Klasse ist endgültig. Wenn Sie einen endgültigen Modifikator für eine Klasse angeben, können Sie verhindern, dass die Klasse vererbt wird, und das Angeben eines endgültigen Modifikators für eine Methode kann verhindern, dass die Methode überschrieben wird. Wenn eine Klasse als endgültig angegeben ist, sind alle Methoden dieser Klasse endgültig. Der Java -Compiler wird nach Möglichkeiten suchen, alle endgültigen Methoden zu inline. Inline ist von großer Bedeutung für die Verbesserung der Effizienz des Java -Betriebs.
2. Versuchen Sie, die Verwendung von Objekten, insbesondere von String -Objekten, wiederzuverwenden. Wenn eine String -Verkettung auftritt, sollte StingBuilder/StringBuffer stattdessen verwendet werden. Da Java -Virtual -Maschinen nicht nur Zeit damit verbringen müssen, Objekte zu generieren, müssen sie möglicherweise auch Zeit damit verbringen, diese Objekte in Zukunft zu sammeln und zu verarbeiten. Die Erzeugung zu viele Objekte hat einen großen Einfluss auf die Leistung des Programms.
3. Verwenden Sie lokale Variablen, um Methoden so weit wie möglich aufzurufen. Die Parameter, die beim Aufruf von Methoden und die im Anruf erstellten temporären Variablen übergeben wurden, werden schneller auf dem Stapel gespeichert. Andere Variablen wie statische Variablen, Instanzvariablen usw. werden im Haufen erstellt, und die Geschwindigkeit ist langsamer. Da die im Stapel erstellten Variablen abgeschlossen sind, sind diese Inhalte weg und es ist keine zusätzliche Müllsammlung erforderlich.
4. Schließen Sie den Fluss rechtzeitig
Seien Sie während der Java -Programmierung vorsichtig, wenn Sie die Datenbankverbindung und I/A -Streaming -Vorgänge ausführen. Schließen Sie es nach dem Gebrauch rechtzeitig, um Ressourcen freizugeben. Da der Betrieb dieser großen Objekte große Systemaufwand verursacht und wenn Sie nicht vorsichtig sind, führt dies zu schwerwiegenden Folgen.
5. Versuchen Sie, die wiederholte Berechnung von Variablen zu minimieren, und klären Sie ein Konzept. Auch wenn die Methode nur einen Satz enthält, wird er dennoch konsumiert, einschließlich des Erstellens von Stapelrahmen, dem Schutz der Website beim Aufrufen der Methode und der Wiederherstellung der Site beim Aufrufen der Methode. Zum Beispiel die folgende Operation:
für (inti = 0; i <list.size (); i ++)
{...} wird empfohlen, es durch zu ersetzen durch:
für (inti = 0, Länge = list.size (); i <Länge; i ++)
{...}
Auf diese Weise reduziert es, wenn list.size () sehr groß ist
6. Versuchen Sie, eine faule Ladestrategie zu verfolgen, dh sie erstellen Sie sie bei Bedarf
7. Verwenden Sie Anomalien mit Vorsicht nachteilig auf die Leistung. Um eine Ausnahme auszulösen, müssen Sie zunächst ein neues Objekt erstellen. Der Konstruktor der Throwable Interface ruft die lokale Synchronisationsmethode mit dem Namen FillInstacktrace () auf. Die Methode FillInstackTrace () überprüft den Stapel und sammelt Call Trace -Informationen. Solange eine Ausnahme ausgelöst wird, muss die java virtuelle Maschine den Anrufstapel anpassen, da während der Verarbeitung ein neues Objekt erstellt wird. Ausnahmen können nur für die Fehlerbehandlung verwendet werden und sollten nicht zur Steuerung des Programmflusses verwendet werden.
8. Verwenden Sie keinen Versuch ... Fang ... In der Schleife sollte es auf der äußersten Schicht platziert werden
Nach den von den Internetnutzern vorgelegten Meinungen denke ich, dass dies diskutiert werden lohnt
9. Wenn Sie die zugefügte Inhaltsdauer schätzen können, geben Sie die anfängliche Länge für die in einem Array implementierten Sammlungs- und Werkzeugklassen an, z. B. ArrayList, Linkedllist, StringBuilder, StringBuffer, HashMap, Hashset usw. Nehmen Sie StringBuilder als Beispiel:
(1) StringBuilder () // Standard für 16 Zeichen (2) StringBuilder (int -Größe) // Standard für 16 Zeichen (3) StringBuilder (String Str) // Standard für 16 Zeichen + Str.Length () Zeichenspeicher zuzuordnen, können Sie die Initialisierungskapazität durch die Konstruktorin der Klasse feststellen (hier beziehen wir uns hier, was uns nur auf die obige Stringbuilder verbessert. Zum Beispiel repräsentiert StringBuilder, Länge die Anzahl der Zeichen, die der aktuelle StringBuilder beibehalten kann. Denn wenn StringBuilder seine maximale Kapazität erreicht, erhöht er seine Kapazität auf das zweifache und fügt 2 hinzu. Wenn StringBuilder seine maximale Kapazität erreicht, muss es ein neues Zeichenarray erstellen und den alten Charakter -Array -Inhalt in das neue Charakter -Array kopieren - dies ist ein sehr leistungsverrückter Vorgang. Stellen Sie sich vor, wenn Sie schätzen können, dass 5000 Zeichen im Charakter -Array ohne Angabe der Länge gespeichert sind, beträgt die Leistung von 2, die 5000 am nächsten liegen, 4096, und die 2, die jeder Erweiterung hinzugefügt werden, ist unabhängig von den 2, dann:
(1) Basierend auf 4096 beantragen Sie 8194-Charakter-Arrays, die gleichzeitig zu 12290-Arrays in Charakter-Arrays addieren. Wenn Sie zu Beginn 5000-Charakter-Arrays angeben können, sparen Sie mehr als doppelt so hoch (2), die die ursprünglichen 4096 Zeichen auf diese Weise in das neue Charakter-Array kopieren, wodurch nicht nur der Speicherplatz verschwendet, sondern auch die Effizienz des Codebetriebs reduziert. Daher ist es nicht falsch, eine angemessene Initialisierungskapazität für die im zugrunde liegenden Array implementierten Sammel- und Werkzeugklassen festzulegen, wodurch sofortige Ergebnisse erzielt werden. Beachten Sie jedoch, dass Sammlungen wie HashMap, die in Arrays + verlinkten Listen implementiert sind, die Anfangsgröße nicht mit Ihrer geschätzten Größe festlegen sollten, da die Möglichkeit eines an eine Tabelle angeschlossenen Objekts fast 0 beträgt. Es wird empfohlen, die Anfangsgröße auf N -Power von 2 zu schätzen.
10. Verwenden Sie beim Kopieren einer großen Datenmenge das System.ArrayCopy () Befehl
11. Multiplikation und Division verwenden Verschiebungsvorgänge
12. Erstellen Sie keine Objektreferenzen kontinuierlich in der Schleife
Zum Beispiel:
für (inti = 1; i <= count; i ++) {Objekt obj = newObject (); }Dieser Ansatz führt zu dem Verweis des Zählenobjekts, auf das im Speicher existiert. Wenn die Anzahl groß ist, wird der Speicher verbraucht. Es wird empfohlen, es zu ändern in:
Objekt obj = null; für (inti = 0; i <= count; i ++) {obj = newObject ();} Auf diese Weise befindet sich im Speicher nur eine Objekt -Objektreferenz. Jedes Mal, wenn New Object () verwendet wird, verweist das Objekt -Objektverweis auf ein anderes Objekt, aber es gibt nur ein Objekt im Speicher, das den Speicherplatz stark speichert.
13. Basierend auf der Berücksichtigung der Effizienz und der Typprüfung sollte Array so weit wie möglich verwendet werden. ArrayList sollte nur verwendet werden, wenn die Array -Größe nicht bestimmt werden kann.
14. Versuchen Sie, HashMap, ArrayList und StringBuilder zu verwenden. Sofern die Thread-Sicherheit dies nicht erfordert, wird nicht empfohlen, Hashtable, Vector und StringBuffer zu verwenden. Die letzten drei haben aufgrund der Verwendung von Synchronisationsmechanismen Leistungsaufwand.
15. Erklären Sie Arrays nicht als öffentliches statisches Finale
Da dies bedeutungslos ist, definiert es nur die Referenz als statisches Finale, und der Inhalt des Arrays kann weiterhin nach Belieben geändert werden. Das Erklären des Arrays als öffentlich ist eine Sicherheitsanfälligkeit, was bedeutet, dass das Array durch externe Klassen geändert werden kann
16. Versuchen Sie, Singletons in geeigneten Gelegenheiten zu verwenden. Die Verwendung von Singletons kann die Lastbelastung reduzieren, die Ladezeit verkürzen und die Belastungseffizienz verbessern. Nicht alle Orte sind jedoch für Singletons geeignet. Einfach ausgedrückt, Singletons sind hauptsächlich für die folgenden drei Aspekte anwendbar:
(1) Steuern Sie die Verwendung von Ressourcen, steuern Sie den gleichzeitigen Zugriff von Ressourcen durch Threadsynchronisation (2) Steuern Sie die Erzeugung von Instanzen, um den Zweck des Speicherns von Ressourcen zu erreichen
17. Versuchen Sie, nach Belieben statische Variablen zu vermeiden
public class a {private static b b = newb (); } Zu diesem Zeitpunkt entspricht der Lebenszyklus der statischen Variablen B wie der von Klasse A. Wenn die Klasse A nicht deinstalliert ist, wird das B -Objekt, auf das durch Referenz B hingewiesen wird, im Speicher, bis das Programm endet
18. Klar keine benötigten Sitzungen mehr rechtzeitig. Um keine aktiven Sitzungen mehr zu löschen, haben viele Anwendungsserver eine Standard -Sitzungs -Timeout, in der Regel 30 Minuten. Wenn der Anwendungsserver mehr Sitzungen speichern muss, überträgt das Betriebssystem einen Teil der Daten auf die Festplatte. Der Anwendungsserver kann auch einige inaktive Sitzungen auf die Festplatte gemäß dem MRU -Algorithmus (am häufigsten verwendet) abgeben und kann sogar nicht genügend Speicherausnahmen ausführen. Wenn die Sitzung auf die Festplatte abgeladen werden soll, muss sie zuerst serialisiert werden. In groß angelegten Clustern ist die Serialisierung von Objekten teuer. Wenn die Sitzung nicht mehr benötigt wird, sollte die Methode von HTTPSession die ungültig () -Methode rechtzeitig aufgerufen werden, um die Sitzung zu löschen.
19. Für Sammlungen, die zufällige Access -Schnittstellen wie ArrayList implementieren, sollten Sie die häufigste für Loop anstelle von für die Eehr -Schleife verwenden, um dies zu durchqueren. Dies wird von JDK an Benutzer empfohlen. Die Erklärung der JDK -API für die RandomAccess -Schnittstelle lautet: Die Implementierung der RandomAccess -Schnittstelle wird verwendet, um anzuzeigen, dass sie einen schnellen Zufallszugriff unterstützt. Der Hauptzweck dieser Schnittstelle ist es, allgemeine Algorithmen ihr Verhalten zu ändern, damit sie eine gute Leistung liefern kann, wenn sie auf zufällige oder kontinuierliche Zugriffslisten angewendet werden. Die praktische Erfahrung zeigt, dass bei der Implementierung von Klasseninstanzen, die die RandomAccess -Schnittstelle im Umlauf haben, zufällig zugegriffen werden, auf die Effizienz der Verwendung normaler für Schleifen höher ist als die Verwendung von Foreach -Schleifen. Umgekehrt ist es effizienter, Iterator zu verwenden, wenn sie nacheinander zugegriffen werden. Sie können Codes verwenden, die den folgenden ähnlichen, um Urteile zu fällen:
if (list InstanceOfRandomaccess) {for (inti = 0; i <list.size (); i ++) {}} else {iterator <?> iterator = list.Iterable (); while (iterator.hasnext ()) {iterator.next ()}} Das zugrunde liegende Implementierungsprinzip von foreach Loop ist der Iterator, sodass die zweite Hälfte des Satzes "wiederum, wenn nacheinander zugegriffen wird, die Verwendung von Iterator effizienter ist", bedeutet, dass auf die nacheinander abgestimmten Klasseninstanzen zugegriffen werden und die Foreach -Schleife verwenden, um zu Traverse.
20. Die Verwendung von synchronisierten Codeblöcken anstelle von Synchronisationsmethoden wurde im Synchronisierungs-Lock-Methode-Block-Artikel im Multi-Thread-Modul sehr deutlich erläutert. Versuchen Sie nicht festzustellen, dass die gesamte Methode synchronisiert werden muss, um synchronisierte Codeblöcke zu verwenden, um die Synchronisierung der Codes zu vermeiden, die nicht synchronisiert werden müssen, was die Codeausführungseffizienz beeinflusst.
21. Deklarieren Sie die Konstanten als statisches Finale und nennen Sie sie im Kapital, damit diese Inhalte während der Kompilierung in den konstanten Pool gebracht werden können, wodurch die Berechnung der erzeugten konstanten Werte während der Laufzeit vermieden werden kann. Darüber hinaus kann die Benennung des Namens einer Konstanten in Kapital auch die Unterscheidung zwischen Konstanten und Variablen erleichtern
22. Erstellen Sie keine nicht verwendeten Objekte, importieren Sie einige nicht verwendete Klassen nicht
Das macht keinen Sinn. Wenn "der Wert der lokalen Variablen I nicht verwendet wird" und "Der Import java.util wird nie verwendet" im Code erscheinen, löschen Sie bitte diese nutzlosen Inhalte
23. Vermeiden Sie die Verwendung von Reflexion während des Programmbetriebs. Weitere Informationen finden Sie unter Reflection. Reflexion ist eine sehr leistungsstarke Funktion von Java für Benutzer. Leistungsstarke Funktionen bedeuten oft eine geringe Effizienz. Es wird nicht empfohlen, den Reflexionsmechanismus beim Ausführen des Programms zu verwenden, insbesondere die Methode der Methode. Wenn dies tatsächlich notwendig ist, besteht ein suggestiver Ansatz darin, ein Objekt durch Reflexion zu instanziieren und es in den Speicher zu bringen, wenn das Projekt gestartet wird. Der Benutzer kümmert sich nur um die schnellste Reaktionsgeschwindigkeit, wenn sie mit dem Peer interagieren, und es ist egal, wie lange es dauert, bis das Peer -Projekt startet.
24. Verwenden Sie den Datenbankverbindungspool und den Thread -Pool, beide Pools, werden verwendet, um Objekte wiederzuverwenden. Ersteres kann das häufige Öffnen und Schließen von Verbindungen vermeiden, und letztere kann eine häufige Schöpfung und Zerstörung von Fäden vermeiden.
25. Verwenden Sie gepufferte Eingangs- und Ausgangsströme für IO -Operationen
Gepufferte Eingangs- und Ausgangsströme, nämlich BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream, der die IO -Effizienz erheblich verbessern kann
26. Verwenden Sie ArrayList für Szenen mit sequentiellerem Einfügen und zufälliger Zugriff und verwenden Sie LinkedList für Szenen mit mehr Elementlöschung und Zwischeneinsatz.
Dies ist bekannt durch das Verständnis der Prinzipien von ArrayList und LinkedList
27. Lassen Sie nicht zu viele formale Parameter in der öffentlichen Methode
Die öffentliche Methode ist eine Methode, die der Außenwelt zur Verfügung gestellt wird. Wenn Sie diesen Methoden zu viele formale Parameter angeben, gibt es zwei Hauptnachteile:
1) Verstoß gegen die objektorientierte Programmierungsidee. Java betont, dass alles ein Objekt ist. Zu viele formale Parameter stimmen nicht mit der objektorientierten Programmierungsidee überein.
2) Zu viele Parameter führen zwangsläufig zu einer Erhöhung der Fehlerwahrscheinlichkeit im Methodenaufruf. Wie viele "zu viele" beziehen sich auf 3 oder 4. Zum Beispiel verwenden wir JDBC, um eine InsertStudentInfo -Methode zu schreiben. Es sind 10 Schülerinformationsfelder, die in die Schülertabelle eingefügt werden müssen. Diese 10 Parameter können in einer Entitätsklasse als formale Parameter der Einfügungsmethode eingekapselt werden.
28. Beim Schreiben von String -Variablen und Stringkonstanten ist es ein relativ häufiger Trick, String Constants vor dem Schreiben von String -Konstanten zu schreiben. Wenn es den folgenden Code gibt:
String str = "123"; if (str.equals ("123") {...} Es wird empfohlen, es zu ändern an:
String str = "123"; if ("123" .Equals (str)) {...} Dies kann hauptsächlich Null -Zeigerausnahmen vermeiden
32. Erzwingen Sie nicht die Abwärtstransformation von grundlegenden Datentypen über den Umfang hinaus
33. Konvertieren Sie einen grundlegenden Datentyp in eine Zeichenfolge. Der grundlegende Datentyp.ToString () ist der schnellste Weg, gefolgt von String.ValueOf (Daten) und Daten + "Der langsamste Weg, um einen grundlegenden Datentyp in drei Arten umzuwandeln. Ich habe einen ganzzahligen Typdaten i, das i.toString (), String.ValueOf (i), i +". "
publicStatic void main (String [] args) {intlooptime = 50000; Ganzzahl i = 0; longStartTime = system.currentTimemillis (); für (intj = 0; j <LoopTime; j ++) {String str = string.ValueOf (i); } System.out.println ("String.ValueOf ():" + (System.currentTimemillis () - StartTime) + "MS"); startTime = system.currentTimemillis (); für (intj = 0; j <LoopTime; j ++) {string str = i.toString (); } System.out.println ("Integer.toString ():" + (System.currentTimemillis () - StartTime) + "MS"); startTime = system.currentTimemillis (); für (intj = 0; j <LoopTime; j ++) {string str = i+""; } System.out.println ("i + /" /":" + (System.currentTimemillis () - StartTime) + "MS");}Das laufende Ergebnis ist:
String.ValueOf (): 11mSintereger.toString (): 5ms + "": 25ms
Wenn Sie in Zukunft einen grundlegenden Datentyp in String konvertieren, sollten Sie die Verwendung der Methode toString () Priorität geben. Was warum ist es sehr einfach:
1. Die methode von String.ValueOf () wird als Integer.ToString () -Methode als unten bezeichnet, fällt jedoch vor dem Anruf ein kurzes Urteilsvermögen.
2. Ich werde nicht über die Integer.ToString () -Methode sprechen, ich werde sie direkt nennen.
3. Die untere Schicht von i + "" verwendet StringBuilder, um es zu implementieren. Verwenden Sie zunächst die Anhang -Methode, um sie zu spleißen, und verwenden Sie dann die Methode toString (), um die Zeichenfolge abzurufen. Es ist offensichtlich die schnellste 2, die schnellste 1 und die langsamste 3.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.