Jaka jest główna różnica między StringBuffer
i StringBuilder
? Czy przy podejmowaniu decyzji dotyczącej któregokolwiek z nich występują problemy z wydajnością?
java
stringbuilder
stringbuffer
czarny tygrys
źródło
źródło
StringBuilder
jest szybszy niżStringBuffer
dlatego, że nie jestsynchronized
.Oto prosty test porównawczy:
Test nie daje numery
2241 ms
dlaStringBuffer
vs753 ms
dlaStringBuilder
.źródło
--> 0
w pętli. Chwilę zajęło mi zrozumienie, co to znaczy. Czy jest to coś, co faktycznie jest używane w praktyce zamiast zwykłej...; i > 0; i--
składni?i -->
jest naprawdę denerwujące pod względem składni ... Na początku myślałem, że to strzała z powodu komentarzy na temat sztuki ASCII.main()
Ponadto test porównawczy jest niesprawiedliwy. Nie ma rozgrzewki.Zasadniczo
StringBuffer
metody są synchronizowane podczasStringBuilder
nie są.Operacje są „prawie” takie same, ale stosowanie metod zsynchronizowanych w jednym wątku to przesada.
To właściwie tyle.
Cytat z StringBuilder API :
Więc został stworzony, aby go zastąpić.
To samo stało się z
Vector
iArrayList
.źródło
Hashtable
iHashMap
.Po prostu użyj,
StringBuilder
chyba że naprawdę próbujesz współdzielić bufor między wątkami.StringBuilder
jest niezsynchronizowanym (mniej narzutu = bardziej wydajnym) młodszym bratem oryginalnej synchronizowanejStringBuffer
klasy.StringBuffer
był pierwszy. Firma Sun martwiła się o poprawność w każdych warunkach, dlatego zsynchronizowała ją, aby na wszelki wypadek była bezpieczna dla wątków.StringBuilder
przyszedł później. Większość zastosowańStringBuffer
była jednowątkowa i niepotrzebnie pokrywała koszty synchronizacji.Ponieważ
StringBuilder
jest zastępczym zamiennikiem dlaStringBuffer
bez synchronizacji, nie byłoby żadnych różnic pomiędzy przykładami.Jeśli są próby akcję pomiędzy wątkami, można użyć
StringBuffer
, ale zastanowić się, czy synchronizacja wyższego poziomu jest konieczne, na przykład może zamiast używać StringBuffer, należy zsynchronizować metody, które wykorzystują StringBuilder.źródło
Najpierw zobaczmy podobieństwa : zarówno StringBuilder, jak i StringBuffer można modyfikować. Oznacza to, że możesz zmienić ich zawartość w tej samej lokalizacji.
Różnice : StringBuffer można również modyfikować i synchronizować. Gdzie jako StringBuilder jest zmienny, ale domyślnie nie jest synchronizowany.
Znaczenie synchronizacji (synchronizacja) : Gdy coś jest synchronizowane, wiele wątków może uzyskać dostęp i modyfikować je bez żadnego problemu lub efektu ubocznego. StringBuffer jest zsynchronizowany, więc możesz używać go z wieloma wątkami bez żadnego problemu.
Którego użyć, kiedy? StringBuilder: Gdy potrzebujesz łańcucha, który można modyfikować, a tylko jeden wątek uzyskuje do niego dostęp i go modyfikuje. StringBuffer: Gdy potrzebujesz łańcucha, który można modyfikować, a wiele wątków ma do niego dostęp i go modyfikuje.
Uwaga : Nie używaj StringBuffer niepotrzebnie, tzn. Nie używaj go, jeśli tylko jeden wątek modyfikuje i uzyskuje do niego dostęp, ponieważ ma dużo kodu blokującego i odblokowującego do synchronizacji, który niepotrzebnie zajmuje czas procesora. Nie używaj zamków, chyba że jest to wymagane.
źródło
W pojedynczych wątkach StringBuffer nie jest znacznie wolniejszy niż StringBuilder , dzięki optymalizacji JVM. W wielowątkowości nie można bezpiecznie używać StringBuilder.
Oto mój test (nie test, tylko test):
Wyniki:
łańcuchy: 319740
Bufory: 23
Konstruktor: 7!
Tak więc Konstruktorzy są szybsi niż bufory i DZIŚ szybciej niż konkatenacja łańcuchów. Teraz użyjmy Executora dla wielu wątków:
Teraz StringBuffers zajmuje 157 ms na 100000 dołączeń. To nie jest ten sam test, ale w porównaniu z poprzednimi 37 ms można bezpiecznie założyć, że dołączenia StringBuffers są wolniejsze przy użyciu wielowątkowości . Powodem jest to, że JIT / hotspot / kompilator / coś dokonuje optymalizacji, gdy wykryje, że nie ma potrzeby sprawdzania blokad.
Ale dzięki StringBuilder masz java.lang.ArrayIndexOutOfBoundsException , ponieważ współbieżny wątek próbuje dodać coś tam, gdzie nie powinno.
Wniosek jest taki, że nie musisz ścigać StringBuffers. A jeśli masz wątki, zastanów się, co robią, zanim spróbujesz uzyskać kilka nanosekund.
źródło
withString+="some string"+i+" ; ";
nie jest to równoważne z pozostałymi dwiema pętlami i dlatego nie jest uczciwym porównaniem.StringBuilder został wprowadzony w Javie 1.5, więc nie będzie działał z wcześniejszymi JVM.
Z Javadocs :
źródło
StringBuilder
.Oto różnice, które zauważyłem:
StringBuffer: -
StringBuilder: -
Zwykła rzecz :-
źródło
StringBuffer
StringBuilder
StringBuffer
bez żadnych innych zmianźródło
append
dwa razy, alboappend
itoString
nie, nie jest bezpieczne.StringBuilder nie jest bezpieczny dla wątków. Bufor ciągów to. Więcej informacji tutaj .
EDYCJA: Jeśli chodzi o wydajność, po uruchomieniu hotspotu StringBuilder jest zwycięzcą. Jednak w przypadku małych iteracji różnica wydajności jest znikoma.
źródło
StringBuilder
iStringBuffer
są prawie takie same. Różnica polega na tym, że nieStringBuffer
jest zsynchronizowanaStringBuilder
. ChociażStringBuilder
jest szybszy niżStringBuffer
, różnica w wydajności jest bardzo mała.StringBuilder
jest zamiennikiem SUN dlaStringBuffer
. Po prostu unika synchronizacji ze wszystkimi publicznymi metodami. Zamiast tego ich funkcjonalność jest taka sama.Przykład dobrego użytkowania:
Jeśli twój tekst ma się zmienić i jest używany przez wiele wątków, lepiej użyć tego
StringBuffer
. Jeśli twój tekst ma się zmienić, ale jest używany przez jeden wątek, użyjStringBuilder
.źródło
StringBuffer
StringBuffer można modyfikować, co oznacza, że można zmienić wartość obiektu. Obiekt utworzony za pomocą StringBuffer jest przechowywany w stercie. StringBuffer ma takie same metody jak StringBuilder, ale każda metoda w StringBuffer jest zsynchronizowana, a StringBuffer jest bezpieczny dla wątków.
z tego powodu nie pozwala dwóm wątkom na jednoczesny dostęp do tej samej metody. Dostęp do każdej metody może mieć jeden wątek na raz.
Ale bycie bezpiecznym dla wątków ma również wady, ponieważ wydajność uderzeń StringBuffer wynika z właściwości bezpiecznych dla wątków. Zatem StringBuilder jest szybszy niż StringBuffer podczas wywoływania tych samych metod dla każdej klasy.
Wartość StringBuffer można zmienić, co oznacza, że można ją przypisać do nowej wartości. W dzisiejszych czasach jest to najczęściej zadawane pytanie dotyczące wywiadu, różnice między powyższymi klasami. Bufor ciągów można przekonwertować na ciąg przy użyciu metody toString ().
StringBuilder
StringBuilder jest taki sam jak StringBuffer, tzn. Przechowuje obiekt w stercie i można go również modyfikować. Główną różnicą między StringBuffer i StringBuilder jest to, że StringBuilder również nie jest bezpieczny dla wątków. StringBuilder jest szybki, ponieważ nie jest bezpieczny dla wątków.
Zasób: String Vs StringBuffer Vs StringBuilder
źródło
String
jest niezmienny.StringBuffer
jest zmienny i zsynchronizowany.StringBuilder
jest również zmienny, ale nie jest zsynchronizowany.źródło
Javadoc wyjaśnia różnicę:
źródło
StringBuilder
(wprowadzony w Javie 5) jest identyczny zStringBuffer
, ale jego metody nie są zsynchronizowane. Oznacza to, że ma lepszą wydajność niż ta ostatnia, ale wadą jest to, że nie jest bezpieczna dla wątków.Przeczytaj samouczek, aby uzyskać więcej informacji.
źródło
Prosty program ilustrujący różnicę między StringBuffer a StringBuilder:
źródło
StringBuffer służy do przechowywania ciągów znaków, które zostaną zmienione (obiektów String nie można zmienić). Automatycznie rozszerza się w razie potrzeby. Powiązane klasy: String, CharSequence.
StringBuilder został dodany w Javie 5. Jest pod każdym względem identyczny z StringBuffer, z wyjątkiem tego, że nie jest zsynchronizowany, co oznacza, że jeśli wiele wątków uzyskuje dostęp do niego w tym samym czasie, mogą wystąpić problemy. W przypadku programów jednowątkowych najczęstszy przypadek, unikając narzutu związanego z synchronizacją, powoduje, że StringBuilder jest nieco szybszy.
źródło
StringBuilder
zwykle są lokalne dla metody, w której są widoczne tylko dla jednego wątku.StringBuffer
jest zsynchronizowany, aleStringBuilder
nie jest. W rezultacieStringBuilder
jest szybszy niżStringBuffer
.źródło
StringBuffer można modyfikować. Może się zmieniać pod względem długości i zawartości. StringBuffer są bezpieczne dla wątków, co oznacza, że mają zsynchronizowane metody kontroli dostępu, dzięki czemu tylko jeden wątek może uzyskać dostęp do zsynchronizowanego kodu obiektu StringBuffer na raz. Tak więc obiektów StringBuffer można ogólnie bezpiecznie używać w środowisku wielowątkowym, w którym wiele wątków może próbować uzyskać dostęp do tego samego obiektu StringBuffer w tym samym czasie.
StringBuilder Klasa StringBuilder jest bardzo podobna do StringBuffer, z tym wyjątkiem, że jej dostęp nie jest zsynchronizowany, więc nie jest bezpieczny wątkowo. Bez synchronizacji wydajność StringBuilder może być lepsza niż StringBuffer. Dlatego jeśli pracujesz w środowisku jednowątkowym, użycie StringBuilder zamiast StringBuffer może spowodować zwiększenie wydajności. Dotyczy to również innych sytuacji, takich jak zmienna lokalna StringBuilder (tj. Zmienna w metodzie), w której tylko jeden wątek będzie uzyskiwał dostęp do obiektu StringBuilder.
źródło
StringBuffer:
StringBuilder
źródło
String c = a + b
jest równoważneString c = new StringBuilder().append(a).append(b).toString()
, więc nie jest szybsze. Tyle tylko, że tworzysz nowy dla każdego przypisania łańcucha, podczas gdy możesz mieć tylko jedno (String d = a + b; d = d + c;
toString d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();
jednocześnieStringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();
uratuje jedno instancje StringBuilder).Konstruktor ciągów :
Bufor ciągów
Zaleca się używanie StringBuilder, gdy tylko jest to możliwe, ponieważ jest szybszy niż StringBuffer. Jeśli jednak bezpieczeństwo wątków jest konieczne, najlepszą opcją są obiekty StringBuffer.
źródło
Lepsze użycie,
StringBuilder
ponieważ nie jest zsynchronizowane i dlatego zapewnia lepszą wydajność.StringBuilder
jest drop-in zamiennikiem starszychStringBuffer
.źródło
StringBu(ff|ild)er
jest to zmienna lokalna używana tylko przez pojedynczy wątek.Ponieważ
StringBuffer
jest zsynchronizowany, wymaga dodatkowego wysiłku, dlatego opiera się na perforamance, jest nieco wolniejszy niżStringBuilder
.źródło
Nie ma żadnych różnic między podstawowymi
StringBuilder
iStringBuffer
istnieją tylko kilka różnic między nimi. WStringBuffer
metodach są zsynchronizowane. Oznacza to, że jednocześnie może działać na nich tylko jeden wątek. Jeśli jest więcej niż jeden wątek, drugi wątek będzie musiał poczekać na zakończenie pierwszego, a trzeci będzie musiał poczekać na zakończenie pierwszego i drugiego itd. Powoduje to, że proces jest bardzo wolny, a tym samym wydajność w przypadkuStringBuffer
jest niska.Z drugiej strony
StringBuilder
nie jest zsynchronizowany. Oznacza to, że wiele wątków może jednocześnie działać na tym samymStringBuilder
obiekcie. To sprawia, że proces jest bardzo szybki, a zatem wydajnośćStringBuilder
jest wysoka.źródło
A
String
jest niezmiennym obiektem, co oznacza, że wartość nie może być zmieniona podczas gdyStringBuffer
jest zmienna.StringBuffer
Są synchronizowane tym samym nić bezpieczny natomiastStringBuilder
nie nadaje się i jest przeznaczona do jednorazowego gwintowany przypadkach.źródło
Główną różnicą jest
StringBuffer
synchronizacja, ale tak nieStringBuilder
jest. Jeśli musisz użyć więcej niż jednego wątku, zalecamy StringBuffer, ale jak na szybkość wykonywaniaStringBuilder
jest większa niżStringBuffer
, ponieważ nie jest zsynchronizowana.źródło
Sprawdź elementy wewnętrzne zsynchronizowanej metody append
StringBuffer
i niezsynchronizowanej metody append zStringBuilder
.StringBuffer :
StringBuilder :
Ponieważ dodatek jest
synchronized
,StringBuffer
ma narzut wydajności w porównaniu doStrinbBuilder
scenariusza wielowątkowego. Tak długo, jak nie udostępniasz bufora wielu wątkom, użyj tegoStringBuilder
, co jest szybkie ze względu na braksynchronized
metod dołączania.źródło
Oto wynik testu wydajności dla String vs StringBuffer vs StringBuilder . Wreszcie StringBuilder wygrał test. Poniżej znajduje się kod testu i wynik.
Kod :
Wykonaj mnie na ideone
Wynik :
100000 iteracji dla dodania pojedynczego tekstu
10000 iteracji dla dodania pojedynczego tekstu
źródło
źródło
StringBuffer jest zsynchronizowany i wątkowo bezpieczny, StringBuilder nie jest synchronizowany i szybszy.
źródło