Ich war an Wochentagen mit der logischen Implementierung des Projekts beschäftigt. Ich hatte am Samstag etwas Zeit, also nahm ich eine dicke englische Version des Denkens in Java aus dem Bücherregal heraus und las das Spleißen von Streichobjekten. Siehe dieses Buch als Übersetzung, fügen Sie hinzu, was Sie denken, und schreiben Sie diesen Artikel, um ihn aufzuzeichnen.
Unveränderliches String -Objekt
In Java sind String -Objekte unveränderlich (unveränderlich). Im Code können Sie mehrere Alias für ein String -Objekt erstellen. Die Referenzen dieser Aliase sind jedoch gleich.
Zum Beispiel sind S1 und S2 Alias für "droidyue.com" -Objekte, und die Alias werden in Bezug auf das reale Objekt gespeichert. Also S1 = S2
String s1 = "droidyue.com"; String S2 = S1; System.out.println ("S1 und S2 hat dieselbe Referenz =" + (S1 == S2));Der einzige überlastete Operator in Java
In Java bezieht sich der einzige überladene Operator mit String -Spleißen. +,+=. Außerdem erlauben Java -Designer keine Überladung anderer Bediener.
Spleißanalyse
Gibt es wirklich eine Leistungskosten?
Nach dem Verständnis der oben genannten zwei Punkte haben Sie möglicherweise solche Gedanken. Da das Sting -Objekt unveränderlich ist, erzeugt das Spleißen mehrerer (drei oder mehr) Zeichenfolgen unweigerlich unnötige Zwischensting -Objekte.
String username = "Andy"; String ay "24"; String Job = "Entwickler"; String Info = Benutzername + Age + Job;
Um die oben genannten Informationen zu erhalten, werden Benutzername und Alter gespleißt, um ein temporäres String -Objekt T1 mit dem Inhalt von Andy24 zu erzeugen, und dann werden T1 und Jobs gespleißt, um das am Ende benötigte Info -Objekt zu generieren. Unter ihnen wird ein mittlerer T1 erzeugt, und nachdem T1 erstellt wurde, wird er nicht automatisch recycelt, was zwangsläufig eine bestimmte Menge an Platz einnimmt. Wenn es sich um viel Spleißen handelt (vorausgesetzt, Hunderte, häufiger im Tastring -Aufruf an das Objekt), sind die Kosten größer und die Leistung wird viel niedriger.
Compiler -Optimierungsverarbeitung
Gibt es wirklich die oben genannten Leistungskosten? String -Spleißen ist so häufig. Gibt es keine spezielle Verarbeitungsoptimierung? Die Antwort ist, dass diese Optimierung durchgeführt wird, wenn der Compiler .java zu Bytecode kompiliert.
Wenn ein Java -Programm ausgeführt werden möchte, dauert es zwei Zeiträume, kompilieren Sie Zeit und Laufzeit. Zum Kompilierzeit wandelt der Java Compiler (Compiler) die Java -Datei in Bytecode um. Zur Laufzeit führt die Java Virtual Machine (JVM) die mit Kompilierung erzeugte Bytecode aus. In diesen beiden Perioden hat Java die sogenannte Zusammenstellung erreicht und überall läuft.
Lassen Sie uns mit den Optimierungen experimentieren, die während der Kompilierungsperiode vorgenommen wurden, und wir erstellen einen Code, der Leistungskosten haben kann.
Public Class Conatenation {public static void main (String [] args) {String username = "andy"; String Age = "24"; String Job = "Entwickler"; String Info = Benutzername + Alter + Job; System.out.println (info); }}Compile concattenation.java. Holen Sie sich cazenation.class
javac concatten.java
Anschließend verwenden wir Javap, um die kompilierte Verkettungsklasse -Datei zu dekompilieren. Javap -c -Verkettung. Wenn der Befehl javap nicht gefunden wird, sollten Sie das Verzeichnis hinzufügen, in dem sich die Javap der Umgebungsvariablen befindet oder den vollständigen Pfad von Javap verwendet.
17: 22: 04 -Androidyue ~/Workspace_ADT/STRINGS/SRC $ JAVAP -C -CONCATENATION COND COMPILED aus "concattenation.java" öffentliche Klassenverhütung {öffentliche Verkettung (); Code: 0: ALOAD_0 1: Invokespecial #1 // Methode Java/Lang/Object. Code: 0: LDC #2 // String Andy 2: Store_1 3: LDC #3 // String 24 5: Store_2 6: LDC #4 // String Developer 8: Store_3 9: Neu #5 // Klasse Java/Lang/StringBuilder 12: Dup 13: Invokespecial #6 // Method Java/Lang/String/Stringbuilder. invokeVirtual #7 // Methode Java/Lang/StringBuilder.Append: (ljava/lang/string;) ljava/lang/stringBuilder; 20: ALOAD_2 21: InvokeVirtual #7 // Methode Java/Lang/StringBuilder.Append: (ljava/lang/String;) ljava/lang/StringBuilder; 24: ALOAD_3 25: InvokeVirtual #7 // Methode Java/Lang/StringBuilder.Append: (ljava/lang/String;) ljava/lang/stringBuilder; 28: InvokeVirtual #8 // Methode Java/Lang/StringBuilder.toString :() Ljava/Lang/String; 31: Store 4 33: Getstatic #9 // Feld Java/Lang/System.out: ljava/io/printstream; 36: ALOAD 4 38: InvokeVirtual #10 // Methode Java/io/printstream.println: (ljava/lang/string;) v 41: return}Unter ihnen sind LDC, Speicher usw. Java -Bytecode -Anweisungen, ähnlich wie Anweisungen für die Montage. Die folgenden Kommentare verwenden Java-bezogene Inhalte zur Erläuterung. Wir können sehen, dass es viele StringBuilders gibt, aber wir nennen sie ohne Anzeige im Java -Code. Dies ist die Optimierung des Java -Compilers. Wenn der Java -Compiler auf String -Spleißen trifft, wird ein StringBuilder -Objekt erstellt. Das Spleißen dahinter besteht darin, die Anhangsmethode des StringBuilder -Objekts zu rufen. Auf diese Weise werden wir keine Probleme geben, über die wir uns Sorgen machen.
Compiler -Optimierung allein?
Seit der Compiler uns geholfen hat, die Optimierung zu optimieren, reicht es aus, sich ausschließlich auf die Optimierung des Compilers zu verlassen? Natürlich nicht.
Schauen wir uns einen Code an, der für niedrige Leistung nicht optimiert wurde
public void implicitusSestringBuilder (String [] Werte) {String result = ""; für (int i = 0; i <values.length; i ++) {result += values [i]; } System.out.println (Ergebnis);}Mit Javac zusammenstellen und mit Javap aussehen
11: Neu #5 // Klasse Java/Lang/StringBuilder 14: DUP 15: Invokespecial #6 // Methode Java/Lang/StringBuilder. java/lang/system.out: ljava/io/printstream; 41: ALOAD_2 42: InvokeVirtual #10 // Methode Java/IO/Printstream.println: (ljava/lang/string;) v 45: Rückkehr
Unter ihnen 8: if_icmpge 38 und 35: Goto 5 bilden eine Schleife. 8: IF_ICMPGE 38 bedeutet, dass, wenn der Ganzzahlvergleich des JVM -Operand -Stapels größer oder gleich ist (das entgegengesetzte Ergebnis von i <values.Length). 35: Goto 5 bedeutet, direkt in Zeile 5 zu springen.
Aber hier gibt es eine sehr wichtige Sache, dass die Erstellung von StringBuilder -Objekten zwischen Schleifen auftritt, was bedeutet, dass die Schleifen, wie oft die Loops StringBuilder -Objekte erstellen, offensichtlich nicht gut ist. Nackter Code mit niedrigem Niveau.
Optimieren Sie es leicht, um die Qualität sofort zu verbessern.
public void explicitusStringBuilder (String [] Werte) {StringBuilder result = new StringBuilder (); für (int i = 0; i <values.length; i ++) {result.append (Werte [i]); }}Entsprechende kompilierte Informationen
public void explicitusStringBuder (Java.lang.String []); Code: 0: Neu #5 // Klasse Java/Lang/StringBuilder 3: DUP 4: Invokespecial #6 // Methode Java/Lang/StringBuilder. ALOAD_1 18: ILOAD_3 19: AALOAD 20: InvokeVirtual #7 // Methode Java/Lang/StringBuilder.Append: (ljava/lang/string;) ljava/lang/StringBuilder; 23: Pop 24: iinc 3, 1 27: Goto 10 30: Rückkehr
Wie aus oben ersichtlich ist, bilden Sie 13: IF_ICMPGE 30 und 27: GOTO 10 eine Schleifenschleife, während 0: Neu #5 außerhalb der Schleife liegt, so dass StringBuilder nicht mehrmals erstellt wird.
Im Allgemeinen müssen wir versuchen, eine implizite oder explizite Erstellung von Stringbuildern im Schleifenkörper zu vermeiden. Daher haben diejenigen, die verstehen, wie der Code zusammengestellt wird und wie er intern ausgeführt wird, relativ hohe Code -Ebenen.
Wenn im obigen Artikel Fehler vorliegen, kritisieren und korrigieren Sie sie bitte.
Das obige ist die Aussortierung der Informationen über das Spleißen von Java -Zeichenfolgen und wir werden in Zukunft weiterhin relevante Informationen hinzufügen. Vielen Dank für Ihre Unterstützung für diese Website!