StringBuffer versus String
Java bietet StringBuffer
und String
Klassen und die String
Klasse wird verwendet , Zeichenketten zu manipulieren , die nicht verändert werden kann. Einfach ausgedrückt, sind Objekte vom Typ String
schreibgeschützt und unveränderlich. Die StringBuffer
Klasse wird verwendet, um Zeichen darzustellen, die geändert werden können.
Der signifikante Leistungsunterschied zwischen diesen beiden Klassen besteht darin, dass er StringBuffer
schneller ist als String
bei einfachen Verkettungen. Im String
Manipulationscode werden Zeichenketten routinemäßig verkettet. Mit der String
Klasse werden Verkettungen normalerweise wie folgt ausgeführt:
String str = neuer String ("Stanford"); str + = "Verloren !!";
Wenn Sie StringBuffer
dieselbe Verkettung ausführen möchten, benötigen Sie Code, der folgendermaßen aussieht:
StringBuffer str = neuer StringBuffer ("Stanford"); str.append ("Lost !!");
Entwickler gehen normalerweise davon aus, dass das erste Beispiel oben effizienter ist, da sie der Meinung sind, dass das zweite Beispiel, bei dem die append
Verkettungsmethode verwendet wird, teurer ist als das erste Beispiel, bei dem der +
Operator zum Verketten von zwei String
Objekten verwendet wird.
Der +
Bediener erscheint unschuldig, aber der generierte Code sorgt für einige Überraschungen. Die Verwendung von a StringBuffer
für die Verkettung kann tatsächlich Code erzeugen, der erheblich schneller ist als die Verwendung von a String
. Um herauszufinden, warum dies der Fall ist, müssen wir den generierten Bytecode aus unseren beiden Beispielen untersuchen. Der Bytecode für das verwendete Beispiel String
sieht folgendermaßen aus:
0 neu # 7 3 dup 4 ldc # 2 6 invokespecial # 12 9 astore_1 10 new # 8 13 dup 14 aload_1 15 invokestatic # 23 18 invokespecial # 13 21 ldc # 1 23 invokevirtual # 15 26 invokevirtual # 22 29 astore_1
Der Bytecode an den Stellen 0 bis 9 wird für die erste Codezeile ausgeführt, nämlich:
String str = neuer String ("Stanford");
Dann wird der Bytecode an den Stellen 10 bis 29 für die Verkettung ausgeführt:
str + = "Verloren !!";
Hier wird es interessant. Der für die Verkettung generierte Bytecode erstellt ein StringBuffer
Objekt und ruft dann seine append
Methode auf: Das temporäre StringBuffer
Objekt wird an Position 10 erstellt und seine append
Methode wird an Position 23 aufgerufen. Da die String
Klasse unveränderlich ist, StringBuffer
muss a für die Verkettung verwendet werden.
Nachdem die Verkettung für das StringBuffer
Objekt durchgeführt wurde, muss es wieder in a konvertiert werden String
. Dies erfolgt mit dem Aufruf der toString
Methode an Position 26. Diese Methode erstellt ein neues String
Objekt aus dem temporären StringBuffer
Objekt. Die Erstellung dieses temporären StringBuffer
Objekts und seine anschließende Umwandlung in ein String
Objekt sind sehr teuer.
Zusammenfassend führen die beiden obigen Codezeilen zur Erstellung von drei Objekten:
- Ein
String
Objekt an Position 0 - Ein
StringBuffer
Objekt an Position 10 - Ein
String
Objekt an Position 26
Betrachten wir nun den für das Beispiel generierten Bytecode mit StringBuffer
:
0 neu # 8 3 dup 4 ldc # 2 6 invokespecial # 13 9 astore_1 10 aload_1 11 ldc # 1 13 invokevirtual # 15 16 pop
Der Bytecode an den Stellen 0 bis 9 wird für die erste Codezeile ausgeführt:
StringBuffer str = neuer StringBuffer ("Stanford");
Der Bytecode an den Positionen 10 bis 16 wird dann für die Verkettung ausgeführt:
str.append ("Lost !!");
Beachten Sie, dass dieser Code wie im ersten Beispiel die append
Methode eines StringBuffer
Objekts aufruft . Im Gegensatz zum ersten Beispiel muss jedoch kein temporäres Objekt erstellt StringBuffer
und anschließend in ein String
Objekt konvertiert werden. Dieser Code erstellt nur ein Objekt, das StringBuffer
an Position 0.
Zusammenfassend ist die StringBuffer
Verkettung erheblich schneller als die String
Verkettung. Offensichtlich sollte StringBuffer
s bei dieser Art von Operation verwendet werden, wenn dies möglich ist. Wenn die Funktionalität der String
Klasse gewünscht wird, sollten Sie a StringBuffer
für die Verkettung verwenden und dann eine Konvertierung in durchführen String
.
Erfahren Sie mehr über dieses Thema
- " JavaWorld stellt neue wöchentliche Java-Leistungsspalte vor", Reggie Hutcherson ( JavaWorld, März 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf.html
- "Die Grundlagen der Java-Leistung", Reggie Hutcherson ( JavaWorld, März 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_2.html
- "Leistungsproblem oder Designproblem?" Reggie Hutcherson ( JavaWorld, März 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_3.html
- "Compiler-Optimierungen", Reggie Hutcherson ( JavaWorld, März 2000)
//www.javaworld.com/jw-03-2000/jw-03-javaperf_4.html
Diese Geschichte "StringBuffer versus String" wurde ursprünglich von JavaWorld veröffentlicht.