StringBuffer a String

Java udostępnia klasy StringBufferi String, a Stringklasa służy do manipulowania ciągami znaków, których nie można zmienić. Mówiąc prosto, obiekty typu Stringsą tylko do odczytu i niezmienne. StringBufferKlasa jest używana do reprezentowania znaków, które mogą być modyfikowane.

Znacząca różnica w wydajności między tymi dwiema klasami polega na tym, że StringBufferjest szybszy niż w Stringprzypadku wykonywania prostych konkatenacji. W Stringkodzie manipulacyjnym ciągi znaków są rutynowo łączone. Przy użyciu Stringklasy konkatenacje są zwykle wykonywane w następujący sposób:

String str = new String („Stanford”); str + = "Lost !!";

Gdybyś miał StringBufferwykonać tę samą konkatenację, potrzebowałbyś kodu, który wygląda następująco:

StringBuffer str = new StringBuffer ("Stanford"); str.append ("Zagubione !!");

Deweloperzy zwykle zakładają, że pierwszy przykład powyżej jest bardziej wydajny, ponieważ uważają, że drugi przykład, w którym zastosowano appendmetodę konkatenacji, jest bardziej kosztowny niż pierwszy przykład, w którym zastosowano +operator do połączenia dwóch Stringobiektów.

+Operator wydaje niewinny, ale kod generowany produkuje kilka niespodzianek. Używanie StringBufferdo konkatenacji może w rzeczywistości generować kod, który jest znacznie szybszy niż użycie String. Aby odkryć, dlaczego tak jest, musimy zbadać wygenerowany kod bajtowy z naszych dwóch przykładów. Kod bajtowy dla przykładu używającego Stringwygląda następująco:

0 nowy # 7 3 dup 4 ldc # 2 6 invokespecial # 12 9 astore_1 10 nowy # 8 13 dup 14 aload_1 15 invokestatic # 23 18 invokespecial # 13 21 ldc # 1 23 invokevirtual # 15 26 invokevirtual # 22 29 astore_1 

Kod bajtowy w lokalizacjach od 0 do 9 jest wykonywany dla pierwszej linii kodu, a mianowicie:

 String str = new String („Stanford”); 

Następnie kod bajtowy w lokalizacjach od 10 do 29 jest wykonywany w celu konkatenacji:

 str + = "Lost !!"; 

Tutaj robi się ciekawie. Kod bajtowy wygenerowany dla konkatenacji tworzy StringBufferobiekt, a następnie wywołuje jego appendmetodę: StringBufferobiekt tymczasowy jest tworzony w położeniu 10, a jego appendmetoda jest wywoływana w położeniu 23. Ponieważ Stringklasa jest niezmienna, StringBufferdo konkatenacji należy użyć a.

Po wykonaniu konkatenacji na StringBufferobiekcie należy go ponownie przekonwertować na plik String. Odbywa się to poprzez wywołanie toStringmetody w lokalizacji 26. Ta metoda tworzy nowy Stringobiekt z StringBufferobiektu tymczasowego . Stworzenie tego tymczasowego StringBufferobiektu i jego późniejsza konwersja z powrotem do Stringobiektu jest bardzo kosztowna.

Podsumowując, dwa wiersze powyższego kodu powodują utworzenie trzech obiektów:

  1. StringObiektu w położeniu 0
  2. StringBufferObiektu w miejscu 10
  3. StringObiektu w miejscu 26

Spójrzmy teraz na kod bajtowy wygenerowany dla przykładu przy użyciu StringBuffer:

0 nowy # 8 3 dup 4 ldc # 2 6 invokespecial # 13 9 astore_1 10 aload_1 11 ldc # 1 13 invokevirtual # 15 16 pop 

Kod bajtowy w lokalizacjach od 0 do 9 jest wykonywany dla pierwszej linii kodu:

 StringBuffer str = new StringBuffer ("Stanford"); 

Kod bajtowy w lokalizacji od 10 do 16 jest następnie wykonywany w celu konkatenacji:

 str.append ("Zagubione !!"); 

Zauważ, że tak jak w pierwszym przykładzie, ten kod wywołuje appendmetodę StringBufferobiektu. Jednak w przeciwieństwie do pierwszego przykładu nie ma potrzeby tworzenia tymczasowego, StringBuffera następnie przekształcania go w Stringobiekt. Ten kod tworzy tylko jeden obiekt StringBuffer, w lokalizacji 0.

Podsumowując, StringBufferkonkatenacja jest znacznie szybsza niż Stringkonkatenacja. Oczywiście, StringBufferjeśli to możliwe , należy używać s w tego typu operacjach. Jeśli Stringwymagana jest funkcjonalność klasy, rozważ użycie StringBufferdo konkatenacji, a następnie wykonanie jednej konwersji do String.

Reggie Hutcherson jest ewangelistą technologii Sun. Ewangelizuje technologie Sun Java 2 Platform na całym świecie, koncentrując się na J2SE i silniku wydajności HotSpot.

Dowiedz się więcej na ten temat

  • JavaWorld debiutuje w nowej cotygodniowej kolumnie dotyczącej wydajności Java”, Reggie Hutcherson ( JavaWorld, marzec 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf.html

  • „Podstawy wydajności języka Java” Reggie Hutcherson ( JavaWorld, marzec 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf_2.html

  • „Problem z wydajnością czy projekt?” Reggie Hutcherson ( JavaWorld, marzec 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf_3.html

  • „Optymalizacje kompilatora”, Reggie Hutcherson ( JavaWorld, marzec 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf_4.html

Ta historia „StringBuffer versus String” została pierwotnie opublikowana przez JavaWorld.