StringBuffer versus String

Java bietet StringBufferund StringKlassen und die StringKlasse wird verwendet , Zeichenketten zu manipulieren , die nicht verändert werden kann. Einfach ausgedrückt, sind Objekte vom Typ Stringschreibgeschützt und unveränderlich. Die StringBufferKlasse wird verwendet, um Zeichen darzustellen, die geändert werden können.

Der signifikante Leistungsunterschied zwischen diesen beiden Klassen besteht darin, dass er StringBufferschneller ist als Stringbei einfachen Verkettungen. Im StringManipulationscode werden Zeichenketten routinemäßig verkettet. Mit der StringKlasse werden Verkettungen normalerweise wie folgt ausgeführt:

String str = neuer String ("Stanford"); str + = "Verloren !!";

Wenn Sie StringBufferdieselbe 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 appendVerkettungsmethode verwendet wird, teurer ist als das erste Beispiel, bei dem der +Operator zum Verketten von zwei StringObjekten verwendet wird.

Der +Bediener erscheint unschuldig, aber der generierte Code sorgt für einige Überraschungen. Die Verwendung von a StringBufferfü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 Stringsieht 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 StringBufferObjekt und ruft dann seine appendMethode auf: Das temporäre StringBufferObjekt wird an Position 10 erstellt und seine appendMethode wird an Position 23 aufgerufen. Da die StringKlasse unveränderlich ist, StringBuffermuss a für die Verkettung verwendet werden.

Nachdem die Verkettung für das StringBufferObjekt durchgeführt wurde, muss es wieder in a konvertiert werden String. Dies erfolgt mit dem Aufruf der toStringMethode an Position 26. Diese Methode erstellt ein neues StringObjekt aus dem temporären StringBufferObjekt. Die Erstellung dieses temporären StringBufferObjekts und seine anschließende Umwandlung in ein StringObjekt sind sehr teuer.

Zusammenfassend führen die beiden obigen Codezeilen zur Erstellung von drei Objekten:

  1. Ein StringObjekt an Position 0
  2. Ein StringBufferObjekt an Position 10
  3. Ein StringObjekt 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 appendMethode eines StringBufferObjekts aufruft . Im Gegensatz zum ersten Beispiel muss jedoch kein temporäres Objekt erstellt StringBufferund anschließend in ein StringObjekt konvertiert werden. Dieser Code erstellt nur ein Objekt, das StringBufferan Position 0.

Zusammenfassend ist die StringBufferVerkettung erheblich schneller als die StringVerkettung. Offensichtlich sollte StringBuffers bei dieser Art von Operation verwendet werden, wenn dies möglich ist. Wenn die Funktionalität der StringKlasse gewünscht wird, sollten Sie a StringBufferfür die Verkettung verwenden und dann eine Konvertierung in durchführen String.

Reggie Hutcherson ist eine Sun-Technologie-Evangelistin. Er evangelisiert die Java 2 Platform-Technologien von Sun auf der ganzen Welt und konzentriert sich dabei auf J2SE und die HotSpot-Performance-Engine.

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.