StringBuilder ve StringBuffer arasındaki fark


Yanıtlar:


1665

StringBuffersenkronize edilir, StringBuilderdeğil.


239
ve StringBuilder, senkronizasyonun gerekli olmadığı StringBuffer'ın yerine bir düşüş olarak tasarlanmıştır
Joel

95
ve senkronizasyon neredeyse hiç gerekli değildir. Birisi bir StringBuilder üzerinde senkronize etmek istiyorsa, tüm kod bloğunu örneğin üzerinde senkronize edilmiş bir (sb) {} ile çevreleyebilir
locka

23
@locka StringBuffer'ın asla iyi bir fikir olmadığını iddia ediyorum (bunu gerektiren bir API'nız yoksa
Peter Lawrey

8
StringBuffer için gördüğüm tek yer çıktı ve çeşitli günlükleme yardımcı programı gibi konsoldur: birçok iş parçacığı çakışmaya neden olabilir. 2 çıktının karışmasını istemediğiniz için ... ancak genellikle StringBuffer düzeyinde senkronizasyon çok düşük seviyede olduğundan, locka yanıtı en iyisi ve StringBuffer kullanımdan kaldırılmalıdır. Yeni başlayanlarla kod inceleme süresinden tasarruf eder.
Remi Morin

20
Bu ikisini karıştıranlar için iyi bir anımsatıcı - BuFFer İlk, daha eski ve bu nedenle senkronize edilmiş bir uygulamadır. Newer Builder sınıfı, Builder kalıbını kullanır ve eşzamansızdır.
Datageek

728

StringBuilderDaha hızlı daha StringBufferÇünkü değil synchronized.

İşte basit bir karşılaştırma testi:

public class Main {
    public static void main(String[] args) {
        int N = 77777777;
        long t;

        {
            StringBuffer sb = new StringBuffer();
            t = System.currentTimeMillis();
            for (int i = N; i --> 0 ;) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }

        {
            StringBuilder sb = new StringBuilder();
            t = System.currentTimeMillis();
            for (int i = N; i > 0 ; i--) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }
    }
}

Bir test çalıştırması sayıları verir 2241 msiçin StringBuffervs 753 msiçin StringBuilder.


10
Dize değişmezini daha büyük bir şeye değiştirdim: "hızlı kahverengi tilki" ve daha ilginç sonuçlar aldım. Temel olarak, yaklaşık olarak hızlılar. Aslında hafızam bitti, bu yüzden birkaç yediyi kaldırmak zorunda kaldım. Açıklama: senkronizasyon etkin nokta tarafından optimize edilir. Temel olarak sadece bunu yapmak için sıcak noktayı gerektiren zamanı ölçüyorsunuz (ve muhtemelen daha fazla optimizasyon).
Jilles van Gurp

7
Daha önce ısınmanız gerekiyor. Bu test StringBuffer için haksızdır. Ayrıca, aslında bir şey eklenmesi iyi olurdu. Aslında, testi çevirdim ve rastgele bir dize ekledim ve karşı testi aldım. Basit ölçütlere güvenemeyeceğini söyler. Bunun tersi StringBuffer'ın daha hızlı olduğunu gösterir. StringBuilder için 5164 vs StringBuffer için 3699 hastebin.com/piwicifami.avrasm
mmm

75
İlk kez --> 0bir döngüde görüyorum . Bunun ne anlama geldiğini anlamam için bir dakikamı aldı. Bu alışılmış ...; i > 0; i--sözdizimi yerine gerçekte kullanılan bir şey mi?
Raimund Krämer

19
Bu i -->gerçekten sinir bozucu bir sözdizimi ... ASCII sanatıyla ilgili yorumlar nedeniyle ilk başta bir ok olduğunu düşündüm.
Sameer Puri

14
Diğerleri farklı sonuçlarla sonuçlanır: alblue.bandlem.com/2016/04/jmh-stringbuffer-stringbuilder.html . Deneyler gerçekten basit değil, JMH ile yapılmalıdır. main()Ayrıca, karşılaştırmalı değerlendirmeniz haksızdır. Isınma yok.
Lukas Eder

249

Temel olarak, StringBufferyöntemler değilken senkronize StringBuilderedilir.

İşlemler "neredeyse" aynıdır, ancak tek bir iş parçacığında senkronize yöntemlerin kullanılması fazladır.

Bu hemen hemen bununla ilgili.

StringBuilder API'sından alıntı :

Bu [StringBuilder] sınıfı, StringBuffer ile uyumlu ancak senkronizasyon garantisi bulunmayan bir API sağlar . Bu sınıf, dize arabelleğinin tek bir iş parçacığı tarafından kullanıldığı yerlerde (genellikle olduğu gibi) StringBuffer için bir yedek değiştirme olarak kullanılmak üzere tasarlanmıştır. Mümkün olduğunda, bu uygulamanın çoğu uygulamada daha hızlı olacağı için StringBuffer'a tercih edilmesi önerilir .

Böylece ikame etmek için yapıldı.

Aynı şey Vectorve ile oldu ArrayList.


1
Ayrıca Hashtableve ile HashMap.
shmosel

176

Ama bir örnek yardımı ile net bir fark elde etmek gerekiyordu?

StringBuffer veya StringBuilder

StringBuilderGerçekten iş parçacıkları arasında bir arabellek paylaşmaya çalışmıyorsanız kullanın . StringBuilderorijinal senkronize StringBuffersınıfın senkronize olmayan (daha az ek yük = daha verimli) küçük erkek kardeşidir .

StringBufferÖnce geldi. Sun her koşulda doğrulukla ilgiliydi, bu yüzden her ihtimale karşı ipliği güvenli hale getirmek için senkronize ettiler.

StringBuildersonra geldi. Kullanımlarının çoğu StringBuffertek iş parçacıklıydı ve senkronizasyonun maliyetini gereksiz yere ödüyordu.

Yana StringBuilderbir olan açılan yerine ilişkin StringBuffersenkronizasyon gerekmeden, herhangi örnekler arasında farklılıklar olmaz.

Eğer varsa vardır parçacıkları arasında pay çalışırken, kullanabileceğiniz StringBuffer, ama belki de yerine StringBuffer kullanmanın örneğin üst seviye eşitleme gerekli olup olmadığını düşünün, siz StringBuilder kullanmak yöntemleri senkronize olmalıdır.


14
İlk iyi cevap !! "İş parçacıkları arasında bir arabellek paylaşmıyorsanız" nokta
AlexWien

1
çok detaylı cevap!
Raúl

81

Önce benzerlikleri görelim : Hem StringBuilder hem de StringBuffer değiştirilebilir. Bu, aynı yerde bulunan içeriklerini değiştirebileceğiniz anlamına gelir.

Farklar : StringBuffer değiştirilebilir ve senkronize edilir. Burada StringBuilder değiştirilebilir, ancak varsayılan olarak senkronize edilmez.

Senkronizasyonun anlamı (senkronizasyon) : Bir şey senkronize edildiğinde, birden fazla iş parçacığı herhangi bir sorun veya yan etki olmadan ona erişebilir ve değiştirebilir. StringBuffer senkronize edilir, böylece herhangi bir sorun olmadan birden fazla iş parçacığı ile kullanabilirsiniz.

Hangisi ne zaman kullanılır? StringBuilder: Değiştirilebilen bir dizeye ihtiyacınız olduğunda ve yalnızca bir iş parçacığına erişip değiştirdiğinizde. StringBuffer: Değiştirilebilen bir dizeye ihtiyacınız olduğunda ve birden çok iş parçacığına erişip değiştirdiğinizde.

Not : StringBuffer'ı gereksiz yere kullanmayın, yani, yalnızca bir iş parçacığı değiştiriyor ve erişiyorsa kullanmayın çünkü senkronizasyon için gereksiz CPU zamanını alacak çok fazla kilitleme ve kilit açma kodu vardır. Gerekli olmadıkça kilitleri kullanmayın.


2
StringBuffer'ın INDIVIDUAL yöntem çağrılarının evre güvenli olduğunu belirtmek isteriz. Ancak birden fazla kod satırınız varsa, bazı kilit / monitörlerle (her zamanki gibi ...) iplik güvenliğini garanti etmek için senkronize bir kod bloğu kullanın. Temel olarak, yalnızca iş parçacığı için güvenli bir kitaplık kullanmanın programınızda iş parçacığı güvenliğini hemen garanti ettiğini varsaymayın!
Kevin Lee

57

Tek iş parçacıklarında, JVM optimizasyonları sayesinde StringBuffer , StringBuilder'den önemli ölçüde yavaş değildir . Ve çoklu kullanımda, bir StringBuilder'ı güvenle kullanamazsınız.

İşte benim test (bir kıyaslama değil, sadece bir test):

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

Sonuçlar:
dizeleri: 319740
Tamponlar: 23
Oluşturucu: 7!

Yani İnşaatçılar Tamponlardan daha hızlı ve WAY dizelerden birleştirme işleminden daha hızlıdır. Şimdi birden çok iş parçacığı için bir Executor kullanalım :

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable<T extends Appendable> implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

Şimdi StringBuffers 100000 için 157 ms sürüyor. Aynı test değil, ancak önceki 37 ms ile karşılaştırıldığında, StringBuffers'ın çok iş parçacıklı kullanımda daha yavaş olduğunu varsayabilirsiniz . Nedeni olduğunu algıladığında JIT / hotspot / derleyici / şey optimizasyonlar sağlamasıdır hiçbir kilitleri kontrol etmek için ihtiyaç.

Ancak StringBuilder ile, eşzamanlı bir iş parçacığı olmaması gereken bir şey eklemeye çalıştığı için java.lang.ArrayIndexOutOfBoundsException var .

Sonuç olarak StringBuffers'ı kovalamak zorunda değilsiniz. Ve ipliklerinizin olduğu yerlerde, birkaç nanosaniye kazanmaya çalışmadan önce ne yaptıklarını düşünün.


5
"T0 = System.currentTimeMillis ();" yapmayı unuttunuz. StringBuilder testi yapmadan önce. StringBuilder için görüntülenen rakam aslında stringbuffer AND stringbuilder testini çalıştırmak için gereken zamandır. Bu satırı ekleyin, StringBuilder'ın İKİ KEZ hakkında daha hızlı olduğunu göreceksiniz.
Gena Batsyan

Bunun withString+="some string"+i+" ; ";diğer iki döngüye eşdeğer olmadığını ve bu nedenle adil bir karşılaştırma olmadığını unutmayın.
Dave Jarvis

Kesin, düzeltildi. Düşünce telleri hala çok yavaş.
Nicolas Zozol

Daha Nedenini açıklayabilir ArrayIndexOutOfBoundsException için zam StringBuilder
Alireza Fattahi

Benchmarklar için JMH kullanmalısınız. Karşılaştırmanız gerçekten yanlış.
Lukas Eder

42

StringBuilder, Java 1.5'te tanıtıldı, böylece önceki JVM'lerle çalışmayacak.

Gönderen Javadocs :

StringBuilder sınıfı, StringBuffer ile uyumlu ancak senkronizasyon garantisi bulunmayan bir API sağlar. Bu sınıf, dize arabelleğinin tek bir iş parçacığı tarafından kullanıldığı yerlerde (genellikle olduğu gibi) StringBuffer için bir yedek değiştirme olarak kullanılmak üzere tasarlanmıştır. Mümkün olduğunda, bu uygulamanın çoğu uygulamada daha hızlı olacağı için StringBuffer yerine kullanılması önerilir.


13
1.4 Kullanım Ömrü Sonunda, bu yüzden 1.5 öncesi için endişelenmeye değmez.
Tom Hawtin - tackline

@ tomHawtin-tackline zorunlu olarak değil - 1.4'ten önce günlük olarak kullandığımız kurumsal ürünler var. Ayrıca BlackBerry java 1.4 tabanlı ve hala çok güncel.
Richard Le Mesurier

CDC ve CLDC de yok StringBuilder.
Jin Kwon

37

Oldukça Güzel Bir Soru

İşte farkları, fark ettim:

StringBuffer: -

StringBuffer is  synchronized
StringBuffer is  thread-safe
StringBuffer is  slow (try to write a sample program and execute it, it will take more time than StringBuilder)

StringBuilder: -

 StringBuilder is not synchronized 
 StringBuilder is not thread-safe
 StringBuilder performance is better than StringBuffer.

Ortak şey: -

Her ikisi de aynı imzalarla aynı yöntemlere sahiptir. Her ikisi de değiştirilebilir.


23

StringBuffer

  • Senkronize dolayısıyla iplik güvenliği
  • İplik güvenli dolayısıyla yavaş

StringBuilder

  • Java 5.0 ile tanışın
  • Asenkron dolayısıyla hızlı ve verimli
  • Kullanıcının isterse açıkça senkronize etmesi gerekir
  • Sen ile değiştirebilirsiniz StringBufferbaşka bir değişiklik olmaksızın

NOT: Yalnızca tek işlemler iş parçacığı için güvenlidir, birden çok işlem değildir. örneğin eğer arama appendiki kez ya appendve toStringgüvenli değil değildir.
Peter Lawrey

22

StringBuilder iş parçacığı için güvenli değil. Dize Arabelleği. Daha fazla bilgi burada .

EDIT: Performans gelince, sıcak nokta başladı sonra , StringBuilder kazanır. Bununla birlikte, küçük iterasyonlar için performans farkı göz ardı edilebilir.


21

StringBuilderve StringBufferneredeyse aynı. Aradaki fark StringBuffersenkronize edilmiş ve StringBuilderdeğil. Daha StringBuilderhızlı olmasına rağmen, StringBufferperformans farkı çok azdır. StringBuilderbir SUN'in yerine geçer StringBuffer. Sadece tüm genel yöntemlerle senkronizasyonu önler. Bunun yerine, işlevleri aynıdır.

İyi kullanım örneği:

Metniniz değişecekse ve birden çok iş parçacığı tarafından kullanılıyorsa, kullanmak daha iyidir StringBuffer. Metniniz değişecek ancak tek bir iş parçacığı tarafından kullanılıyorsa, kullanın StringBuilder.


19

StringBuffer

StringBuffer değiştirilebilir, nesnenin değerini değiştirebileceğiniz anlamına gelir. StringBuffer ile oluşturulan nesne yığın içinde saklanır. StringBuffer, StringBuilder ile aynı yöntemlere sahiptir, ancak StringBuffer'daki her yöntem, StringBuffer'ın iş parçacığı için güvenli olduğu senkronize edilir.

Bu nedenle, iki iş parçacığının aynı anda aynı yönteme erişmesine izin vermez. Her yönteme bir seferde bir iş parçacığıyla erişilebilir.

Ancak iş parçacığı güvenli olmanın dezavantajları vardır, çünkü iş parçacığı güvenli özelliği nedeniyle StringBuffer'ın performansı vurur. Böylece StringBuilder, her sınıfın aynı yöntemlerini çağırırken StringBuffer'dan daha hızlıdır.

StringBuffer değeri değiştirilebilir, yeni değere atanabileceği anlamına gelir. Günümüzde en yaygın görüşme sorusu olan yukarıdaki sınıflar arasındaki farklar. String Buffer, toString () yöntemi kullanılarak dizeye dönüştürülebilir.

StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .

demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer

StringBuilder

StringBuilder, StringBuffer ile aynıdır, yani nesneyi yığın halinde saklar ve ayrıca değiştirilebilir. StringBuffer ve StringBuilder arasındaki temel fark StringBuilder'ın iş parçacığı için güvenli olmamasıdır. StringBuilder, iş parçacığı güvenli olmadığından hızlıdır.

StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder

resim açıklamasını buraya girin

Kaynak: String Vs StringBuffer Vs StringBuilder


StringBuilder değişmez ve String tipi değiştirilebilir
Brinda Rathod

Dizeleri ve StringBuilders "hızlı" ve StringBuffers "çok yavaş" olduğunu kabul etmem. Yukarıdaki cevaplara bakınız.
FireCubez

17

String değişmezdir.

StringBuffer değişebilir ve senkronize.

StringBuilder aynı zamanda değişkendir ancak senkronize değildir.


Ayrıca StringBuffer, iş parçacığı güvenli verilere erişmek için iş parçacığı kilitler, bu nedenle işlem yavaş gidiyor. StringBuilder iş parçacığı kilitlemez ve Multi Threading şekilde çalışır, bu yüzden hızlıdır. String - dizeyi birleştirmeniz gerekmediğinde bu iyi bir yoldur, ancak ihtiyacınız olduğunda StringBuilder -> kullanın çünkü String yığınta her yeni Nesne oluşturduğunda, ancak StringBuilder aynı nesneyi döndürür ...
Musa

11

Javadoc farkını açıklıyor:

Bu sınıf, StringBuffer ile uyumlu ancak senkronizasyon garantisi bulunmayan bir API sağlar. Bu sınıf, dize arabelleğinin tek bir iş parçacığı tarafından kullanıldığı yerlerde (genellikle olduğu gibi) StringBuffer için bir yedek değiştirme olarak kullanılmak üzere tasarlanmıştır. Mümkün olduğunda, bu uygulamanın çoğu uygulamada daha hızlı olacağı için StringBuffer yerine kullanılması önerilir.


10

StringBuilder(Java 5'te tanıtıldı), StringBufferyöntemleri senkronize edilmedikçe aynıdır . Bu, ikincisinden daha iyi bir performansa sahip olduğu anlamına gelir, ancak dezavantajı, iplik güvenli olmamasıdır.

Daha fazla bilgi için öğreticiyi okuyun .


6

StringBuffer ve StringBuilder arasındaki farkı gösteren basit bir program:

/**
 * Run this program a couple of times. We see that the StringBuilder does not
 * give us reliable results because its methods are not thread-safe as compared
 * to StringBuffer.
 * 
 * For example, the single append in StringBuffer is thread-safe, i.e.
 * only one thread can call append() at any time and would finish writing
 * back to memory one at a time. In contrast, the append() in the StringBuilder 
 * class can be called concurrently by many threads, so the final size of the 
 * StringBuilder is sometimes less than expected.
 * 
 */
public class StringBufferVSStringBuilder {

    public static void main(String[] args) throws InterruptedException {

        int n = 10; 

        //*************************String Builder Test*******************************//
        StringBuilder sb = new StringBuilder();
        StringBuilderTest[] builderThreads = new StringBuilderTest[n];
        for (int i = 0; i < n; i++) {
            builderThreads[i] = new StringBuilderTest(sb);
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].join();
        }
        System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());

        //*************************String Buffer Test*******************************//

        StringBuffer sb2 = new StringBuffer();
        StringBufferTest[] bufferThreads = new StringBufferTest[n];
        for (int i = 0; i < n; i++) {
            bufferThreads[i] = new StringBufferTest(sb2);
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].join();
        }
        System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());

    }

}

// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {

    StringBuilder sb;

    public StringBuilderTest (StringBuilder sb) {
        this.sb = sb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb.append("A");
        }

    }
}


//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {

    StringBuffer sb2;

    public StringBufferTest (StringBuffer sb2) {
        this.sb2 = sb2;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb2.append("A");
        }

    }
}

4

StringBuffer değiştirilecek karakter dizelerini saklamak için kullanılır (Dize nesneleri değiştirilemez). Gerektiğinde otomatik olarak genişler. İlgili sınıflar: String, CharSequence.

StringBuilder, Java 5'e eklenmiştir. Senkronize olmaması dışında StringBuffer ile her bakımdan aynıdır; bu, aynı anda birden çok iş parçacığına erişiyorsa sorun olabileceği anlamına gelir. Tek iş parçacıklı programlar için, en sık karşılaşılan durum, eşitleme yükünden kaçınmak StringBuilder'ı çok daha hızlı hale getirir.


4
Tek iş parçacıklı programlar Java'da en yaygın durum değildir, ancak StringBuilder‍'ler genellikle yalnızca bir iş parçacığının görebildiği bir yöntem için yereldir.
finnw

4

StringBuffersenkronize edildi, ancak StringBuilderdeğil. Sonuç olarak, StringBuilderdaha hızlıdır StringBuffer.


4

StringBuffer değiştirilebilir. Uzunluk ve içerik olarak değişebilir. StringBuffers iş parçacığı için güvenlidir, yani bir seferde yalnızca bir iş parçacığının StringBuffer nesnesinin eşitlenmiş koduna erişebilmesi için erişimi denetlemek üzere eşitlenmiş yöntemlere sahip oldukları anlamına gelir. Bu nedenle, StringBuffer nesnelerinin, birden çok iş parçacığının aynı StringBuffer nesnesine aynı anda erişmeye çalıştığı çok iş parçacıklı bir ortamda kullanılması genellikle güvenlidir.

StringBuilder StringBuilder sınıfı, StringBuffer'a çok benzer, ancak erişiminin iş parçacığı için güvenli olmaması için eşitlenmemesi dışında. Eşitlenmeyerek, StringBuilder performansı StringBuffer'dan daha iyi olabilir. Bu nedenle, tek iş parçacıklı bir ortamda çalışıyorsanız, StringBuffer yerine StringBuilder kullanmak performans artışı ile sonuçlanabilir. Bu, StringBuilder yerel değişkeni (yani, yöntem içindeki bir değişken) gibi yalnızca bir iş parçacığının bir StringBuilder nesnesine erişeceği diğer durumlar için de geçerlidir.


4

StringBuffer:

  • Çoklu dizin
  • Senkronize
  • StringBuilder'dan daha yavaş

StringBuilder

  • Tek Konu
  • Eşzamanlılaştırılmış Değil
  • Hiç olmadığı kadar hızlı String

2
Daha doğrusu, String c = a + beşdeğerdir String c = new StringBuilder().append(a).append(b).toString(), bu yüzden daha hızlı değildir. Bu yalnızca bir tane olabilir ederken, her dize assignation için yeni bir tane oluşturun bu sadece ( String d = a + b; d = d + c;bir String d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();süre StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();tek StringBuilder instanciation kurtarmak olacaktır).
Chop

4

String-Builder :

int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.

String Tampon

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

StringBuffer'dan daha hızlı olduğu için mümkün olduğunda StringBuilder kullanılması önerilir. Ancak, iş parçacığı güvenliği gerekirse, en iyi seçenek StringBuffer nesneleridir.


İş parçacığı güvenliğine ihtiyacınız varsa, en iyi seçenek StringBuilder'ı kullanmaktır çünkü StringBuffer yalnızca bireysel işlemler için iş parçacığı için güvenlidir. Birden fazla işlem için açık kilitleme yapmanız gerekir.
Peter Lawrey

4

SenkronizeStringBuilder olmadığı ve bu nedenle daha iyi performans sunduğu için daha iyi kullanım . Bir olan açılan yerine daha büyük .StringBuilderStringBuffer


3
@Mark true ama çoğu zaman StringBu(ff|ild)eryalnızca tek bir iş parçacığı tarafından kullanılan yerel bir değişkendir.
gabuzo

1
@MarkMcKenna: Çok iş parçacıklı bir uygulamada bile, genellikle harici kilitleme kullanmak veya önlemek için fazladan iş yapmak gerekir. Örneğin, iki iş parçacığının her biri bir dize oluşturucuya birden çok dize içeren bir kayıt eklemek isterse, eklenecek verileri toplaması ve daha hızlı olsa bile bir birim olarak eklemesi gerekir - iş parçacığı sorunları yok-- basitçe ayrı ekleme işlemleri dizisi gerçekleştirmek için.
Supercat

3

Yana StringBuffersenkronize edilir, bu nedenle perforamance dayalı bazı ekstra çaba gerekiyor, onun bir daha yavaş ısırdı StringBuilder.


3

Aralarında temel bir fark yoktur StringBuilderve aralarında StringBuffersadece birkaç fark vardır. Gelen StringBufferyöntemlerle senkronize edilir. Bu, bir seferde sadece bir iplik çalışabileceği anlamına gelir. Birden fazla iş parçacığı varsa, ikinci iş parçacığının ilk iş parçasının bitmesini beklemesi gerekir ve üçüncü iş parçacığının birinci ve ikinci iş parçasının bitmesini beklemesi gerekir. Bu, süreci çok yavaşlatır ve dolayısıyla performans StringBufferdüşüktür.

Öte yandan, StringBuildersenkronize değildir. Bu StringBuilder, aynı anda aynı nesne üzerinde aynı anda birden fazla iş parçacığının çalışabileceği anlamına gelir . Bu işlemi çok hızlı hale getirir ve dolayısıyla performansı StringBuilderyüksektir.


3

Bir Stringgelir değişmez bir amacı değeri değiştirilemez ise StringBufferdeğişkendir.

StringBufferDolayısıyla Senkronize evreli ise olan StringBuilder, yalnızca tek dişli örnekleri için değil ve uygundur.


3
StringBuffer'ın senkronize edilmiş bir kod içermesi, StringBuffer'ın threadsafe olduğu anlamına gelmez. Aşağıdaki örneği düşünün: StringBuffer testingBuffer = "stackoverflow"; Şimdi Thread-1, testBuffer'a "1" eklemeye çalışıyor ve Thread-2, testingBuffer'a "2" eklemeye çalışıyor. Şimdi append () yöntemi senkronize olsa bile, testBuffer değerinin "stackoverflow12" veya "stackoverflow21" olup olmayacağından emin olamıyorum. Aslında, Oracle tarafından stringbuffer üzerinden stringbuilder kullanılması tavsiye edilir. Umarım bu yardımcı olmuştur :)
Biman Tripathy

2

En önemli fark edilir StringBuffersyncronized ancak StringBuilderyürütme hızı göre birden fazla iş parçacığı kullanmak gerekir not.If, daha sonra StringBuffer recommended.But olduğu StringBuilderdaha hızlı olduğu StringBufferonun syncronized değil, çünkü.


4
StringBuffer yalnızca üzerinde bir işlem gerçekleştirirseniz iş parçacığı için güvenlidir. Doğru almak çok zor olduğu için birden fazla iş parçacığında kullanmanızı tavsiye etmem.
Peter Lawrey

@PeterLawrey ne demek istiyorsun? :-)
Tamad Lang

1
@ b16db0 StringBuffer'ın çoğu kullanımının, dış senkronizasyon olmadan çoklu çağrılar yaptıklarından, sınıfı oldukça anlamsız kıldığından, iş parçacığı için güvenli olmadığı anlamına gelir.
Peter Lawrey

@PeterLawrey ah StringBuffer'ın hala senkronize bir ortama ihtiyacı var.
Tamad Lang

2

Öğesinin senkronize ekleme yönteminin StringBufferve senkronize olmayan ekleme yönteminin iç kısımlarını kontrol edin StringBuilder.

StringBuffer :

public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}

public synchronized StringBuffer append(Object obj) {
    super.append(String.valueOf(obj));
    return this;
}

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

StringBuilder :

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Ekleme olduğu synchronized, StringBufferkıyasla performans yüke sahiptir StrinbBuildersenaryo çoklu iş parçacığı. Tamponu birden fazla iş parçacığı arasında paylaşmadığınız sürece , ekleme yöntemlerinin StringBuilderolmaması nedeniyle hızlı kullanın synchronized.


1

İşte String vs StringBuffer vs StringBuilder için performans testi sonucu . Son olarak, StringBuilder Testi kazandı. Test kodu ve sonucu için aşağıya bakın.

Kod :

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

Beni ideone üzerinde yürüt

Sonuç :

Tek bir metin eklemek için 100000 yineleme

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

Tek bir metin eklemek için 10000 yineleme

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms

1
  • StringBuffer iş parçacığı için güvenli ancak StringBuilder iş parçacığı için güvenli değil.
  • StringBuilder, StringBuffer'dan daha hızlıdır.
  • StringBuffer senkronize edilirken StringBuilder senkronize edilmez.

1

StringBuffer senkronize ve iş parçacığı için güvenli, StringBuilder senkronize ve daha hızlı değil.


Bu fark, bu sorunun diğer tüm cevaplarında verilmiştir. Yeni bir şey vurgulayabilir misiniz?
Nico Haase
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.