Frage

Was ist der größte Unterschied zwischen StringBuffer und StringBuilder? Gibt es irgendwelche Performance-Probleme, wenn sie auf einem dieser Entscheidung?

War es hilfreich?

Lösung

StringBuffer synchronisiert, StringBuilder nicht.

Andere Tipps

StringBuilder ist schneller als StringBuffer weil es nicht synchronized.

Hier ist ein einfacher Benchmark-Test:

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);
        }
    }
}

Testlauf die Zahlen von 2241 ms für StringBuffer vs 753 ms für StringBuilder gibt.

Grundsätzlich StringBuffer Methoden synchronisiert werden, während StringBuilder nicht.

Die Operationen sind „fast“ die gleiche, aber in einem einzigen Thread synchronisiert Methoden sind übertrieben.

Das ist ziemlich viel über sie.

Zitat von String API :

  

Diese Klasse [String] stellt eine API kompatibel mit String, aber ohne Garantie der Synchronisation . Diese Klasse wird als Drop-in-Ersatz für den Einsatz für die Stringbuffer an Orten, wo der String-Puffer durch einen einzelnen Thread verwendet wurde (wie es im Allgemeinen der Fall ist). Wo es möglich ist, empfiehlt es sich, dass diese Klasse in den Vorzug String verwendet werden, wie es wird schneller unter den meisten Implementierungen.

So wurde es gemacht, es zu ersetzen.

Das gleiche geschah mit Vector und ArrayList.

  

Aber notwendig, um die klare Differenz mit Hilfe eines Beispiels zu bekommen?

     

oder Stringstring

Verwenden Sie einfach StringBuilder, wenn Sie wirklich einen Puffer zwischen Threads versuchen, zu teilen. StringBuilder ist der unsynchronisierte (weniger Overhead = effizienten) jüngerer Bruder der ursprünglichen synchronisierten StringBuffer Klasse.

StringBuffer kam zuerst. Sun wurde mit Korrektheit unter allen Bedingungen betrifft, so machten sie es synchronisiert es Thread-sicher zu machen, nur für den Fall.

StringBuilder kam später. Die meisten der Anwendungen von StringBuffer waren eingängig und unnötig die Kosten für die Synchronisation zu zahlen.

Da StringBuilder ist ein -Ersatz und für StringBuffer ohne Synchronisation, gäbe es nicht zwischen irgendwelchen Beispielen Unterschiede geben.

Wenn Sie ist versuchen, zwischen Threads zu teilen, können Sie StringBuffer verwenden, aber prüfen, ob übergeordnete Synchronisation erforderlich ist, z.B. vielleicht anstelle von String, sollten Sie die Methoden synchronisieren, die die Stringbuilder verwenden.

Zuerst lässt die Ähnlichkeiten sehen : Sowohl Stringbuilder und String sind wandelbar. Das bedeutet, dass Sie den Inhalt von ihnen ändern können, mit an der gleichen Stelle.

Unterschiede : Stringbuffer Wandelbare und auch synchronisiert. Wo, wie String wandelbar ist aber nicht standardmäßig synchronisiert.

Bedeutung der synchronisierten (Synchronisation) : Wenn ein Ding synchronisiert ist, dann können mehrere Threads öffnen und ändern Sie es ohne jede Probleme oder Nebenwirkung. String synchronisiert, so dass Sie es mit mehreren Threads verwenden, um mit aus jedem Problem.

Was man zu verwenden, wenn? String: Wenn Sie eine Zeichenfolge benötigen, die veränderbar sein kann und nur ein Thread zugreift und sie zu verändern. String:. Wenn Sie eine Zeichenfolge benötigen, die veränderbar sein kann, und mehrere Threads zugreifen und es zu ändern

Hinweis : Sie String nicht unnötig verwenden, das heißt, verwenden Sie es nicht, wenn nur ein Thread zu modifizieren und den Zugriff auf sie, weil sie viel Verriegeln und Entriegeln Code zur Synchronisation hat, die unnötig nehmen up CPU-Zeit. Keine Sperren verwenden, wenn es erforderlich ist.

In einzelnen Fäden, String nicht wesentlich langsamer als String , dank JVM Optimierungen. Und in Multithreading, können Sie nicht sicher einen Stringbuilder verwenden.

Hier ist mein Test (kein Benchmark, nur einen 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));
}

Ergebnisse:
Strings: 319740
Puffer: 23
Builder: 7

So Builders ist schneller als Puffer, und viel schneller als Strings Verkettung. Lassen Sie uns nun ein Executor für mehrere Threads verwenden:

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);
    }
}

Jetzt Stringbuffers nehmen 157 ms für 100000 anhängt. Es ist nicht der gleiche Test, aber im Vergleich zu den vorherigen 37 ms können Sie sicher davon ausgehen, dass die Stringbuffers Appends sind langsamer mit Multithreading Verwendung . Der Grund dafür ist, dass der JIT / Hotspot / Compiler / etwas Optimierungen macht, wenn es erkennt, dass es nicht Notwendigkeit für Schlösser zu überprüfen.

Aber mit String, Sie haben java.lang.ArrayIndexOutOfBoundsException , da ein gleichzeitiger Thread etwas hinzufügen versucht, wo es nicht sollte.

Schlussfolgerung ist, dass Sie müssen nicht Stringbuffers jagen. Und wo Sie Threads haben, darüber nachzudenken, was sie tun, bevor Sie versuchen, ein paar Nanosekunden zu gewinnen.

Stringbuilder in Java eingeführt wurde, 1,5, damit es nicht mit früheren JVMs arbeiten.

Von der Javadocs :

  

Stringbuilder-Klasse stellt eine API kompatibel mit String, aber ohne Garantie für die Synchronisation. Diese Klasse wird als Drop-in-Ersatz für den Einsatz für die Stringbuffer an Orten, wo der String-Puffer durch einen einzelnen Thread verwendet wurde (wie es im Allgemeinen der Fall ist). Wo es möglich ist, wird empfohlen, dass diese Klasse in den Vorzug String verwendet werden, da es schneller sein wird, unter den meisten Implementierungen.

  

Pretty Good Question

Hier sind die Unterschiede, ich habe bemerkt:

String: -

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)

String: -

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

Gemeinsame Sache: -

  

Beide haben gleiche Verfahren mit gleichen Unterschriften. Beide sind wandelbar.

String ist nicht Thread-sicher. String-Puffer ist. Weitere Informationen hier .

EDIT: Was die Leistung, nach dem Hotspot anspringt, Stringbuilder ist der Gewinner. Doch für kleine Iterationen, der Performance-Unterschied ist zu vernachlässigen.

StringBuilder und StringBuffer sind fast gleich. Der Unterschied besteht darin, dass StringBuffer synchronisiert ist und StringBuilder nicht. Obwohl StringBuilder schneller als StringBuffer ist, ist der Unterschied in der Leistung sehr wenig. StringBuilder ist ein Ersatz der SUN von StringBuffer. Es vermeidet nur die Synchronisation von allen öffentlichen Methoden. Vielmehr als das, ist ihre Funktionalität gleich.

Beispiel für eine gute Nutzung:

Wenn Sie Ihr Text ändern wird und wird von mehreren Threads verwendet wird, dann ist es besser StringBuffer zu verwenden. Wenn Ihr Text ändern wird, sondern von einem einzigen Thread verwendet wird, dann StringBuilder verwenden.

StringBuffer

  • Synchronisierte daher THREAD
  • Thread sicher daher langsam

StringBuilder

  • Eingeführt in Java 5.0
  • Asynchronous daher schnell und effizient
  • Der Benutzer muss explizit synchronisieren, wenn er will
  • Sie können es mit StringBuffer ersetzen ohne weitere Änderung

String

String wandelbar ist, bedeutet, man den Wert des Objekts ändern können. Das Objekt erstellt durch String wird in dem Heap gespeichert. Stringbuffer hat die gleichen Methoden wie der String, aber jedes Verfahren in Stringbuffer synchronisiert ist, der Stringbuffer ist threadsicher.

, weil dieser es erlaubt nicht zwei Threads die gleiche Methode gleichzeitig zuzugreifen. Jedes Verfahren kann von einem Thread zu einem Zeitpunkt zugegriffen werden.

Aber sicher Gewinde hat auch Nachteile, wie die Leistung des String aufgrund trifft sicher Eigentum fädeln. So Stringbuilder ist schneller als die String wenn die gleichen Methoden jeder Klasse aufrufen.

Stringwert kann geändert werden, es bedeutet, dass es auf den neuen Wert zugewiesen werden. Heute ist es eine häufigstene Interviewfrage, die Unterschiede zwischen den oben genannten Klassen. String Buffer kann auf den String umgewandelt werden, indem unter Verwendung von toString () -Methode.

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

String

String ist gleich der String, dh es speichert das Objekt in Haufen und es kann auch geändert werden. Der Hauptunterschied zwischen dem Stringbuffer und String ist, dass String ist auch nicht sicher fädeln. Stringbuilder ist schnell, da es nicht sicher ist, fädelt.

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

 image description hier

Resource: String Vs String Vs String

String ist ein unveränderliches.

StringBuffer ist ein veränderliches und synchronisiert.

StringBuilder ist auch wandelbar, aber es ist nicht synchronisiert.

Der javadoc den Unterschied erklärt:

  

Diese Klasse stellt eine API mit String kompatibel, aber ohne Garantie für die Synchronisation. Diese Klasse wird als Drop-in-Ersatz für den Einsatz für die Stringbuffer an Orten, wo der String-Puffer durch einen einzelnen Thread verwendet wurde (wie es im Allgemeinen der Fall ist). Wo es möglich ist, empfiehlt es sich, dass diese Klasse in den Vorzug String verwendet werden, da es schneller sein wird, unter den meisten Implementierungen.

StringBuilder (eingeführt in Java 5) ist identisch mit StringBuffer, mit Ausnahme ihrer Methoden nicht synchronisiert sind. Das bedeutet, es eine bessere Leistung als die letztere hat, aber der Nachteil ist, dass es nicht Thread-sicher ist.

Lesen Tutorial für weitere Details.

Ein einfaches Programm, welches die Differenz zwischen String und String:

/**
 * 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");
        }

    }
}

Bessere Nutzung Stringbuilder, da es nicht synchronisiert ist und dafür eine bessere Leistung. Stringbuilder ist ein Drop-in-Ersatz des älteren String.

StringBuffer synchronisiert, aber StringBuilder nicht. Als Ergebnis ist StringBuilder schneller als StringBuffer.

String Wandelbare. Es kann in Bezug auf Länge und Inhalt verändern. Stringbuffers Thread-sicher ist, was bedeutet, dass sie Methoden synchronisiert haben Zugriff zu steuern, so dass nur ein Thread ein Stringobjekts synchronisierten Code zu einem Zeitpunkt zugreifen kann. Somit sind String Objekte im Allgemeinen sicher in einer Multi-Thread-Umgebung zu verwenden, in denen mehrere Threads das gleiche String Objekt zur gleichen Zeit zuzugreifen versuchen können.

String Die Klasse String ist sehr ähnlich wie String, mit der Ausnahme, dass der Zugriff nicht synchronisiert ist, so dass es nicht Thread-sicher. Durch die nicht synchronisiert werden, kann die Leistung von String besser sein als String. Somit wird bei erhöhter Leistung, wenn Sie in einer Singlethread-Umgebung arbeiten, mit Stringbuilder statt String führen. Dies gilt auch für andere Situationen, wie beispielsweise eine String lokale Variablen (dh einer Variable in einem Verfahren), in dem nur ein Thread ein Stringobjekt sein erreichbar.

String:

  • Multi-Thread
  • Synchronisierte
  • Langsame als String

String

  • Single-Thread
  • Nicht-Synchron
  • Schneller als je zuvor String

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-Buffer

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

Es wird empfohlen, Stringbuilder zu verwenden, wann immer möglich, weil es schneller als String ist. Wenn jedoch die Thread-Sicherheit erforderlich ist, ist die beste Option String Objekte.

String zum Speichern von Zeichenketten verwendet wird, die geändert werden (String-Objekte können nicht geändert werden). Es erweitert sich automatisch je nach Bedarf. Verwandte Klassen:. String, CharSequence

String wurde in Java hinzugefügt 5. Es ist in jeder Hinsicht identisch mit Ausnahme String ist, dass es nicht synchronisiert ist, was bedeutet, dass, wenn mehrere Threads es zur gleichen Zeit zugreifen, es Ärger geben könnte. Für Single-Threaded-Programme, der häufigste Fall, den Aufwand für die Synchronisation zu vermeiden macht den String sehr geringfügig schneller.

Es gibt keine grundlegenden Unterschiede zwischen String und String, nur wenige Unterschiede zwischen ihnen. In Stringbuffer werden die Verfahren synchronisiert. Dies bedeutet, dass eine zu einem Zeitpunkt nur Thread auf sie arbeiten kann. Wenn es mehr als einen Thread sind, dann wird der zweite Thread müssen warten, die erste zu beenden und die dritte wird für die erste und zweite warten, zu beenden und so weiter. Dies macht das Verfahren sehr langsam und damit die Leistung bei String gering ist.

Auf der anderen Seite ist nicht String synchronisiert. Dies bedeutet, dass mehrere Threads zu einem Zeitpunkt auf dem gleichen StrinBuilder Objekt gleichzeitig arbeiten kann. Dies macht das Verfahren sehr schnell und damit die Leistung von String hoch ist.

Da StringBuffer synchronisiert ist, braucht es etwas mehr Mühe, damit basierend auf perforamance, es ist ein bisschen langsam als StringBuilder.

String ist ein unveränderliches Objekt, das den Wert bedeutet, kann nicht geändert werden, wenn als String wandelbar ist.

Die String synchronisiert ist daher sicher Thread, in dem als Stringbuilder ist nicht und eignet sich für nur einzelne Gewinde Instanzen.

Der große Unterschied ist StringBuffer syncronized ist aber StringBuilder ist not.If Sie mehr als ein Thread verwenden müssen, dann ist String recommended.But, gemäß der Ausführungsgeschwindigkeit StringBuilder ist schneller als StringBuffer, denn es ist nicht synchronisiert.

Überprüfen Sie die Interna der synchronisierten Methode append von StringBuffer und nicht synchronisierte Methode append von StringBuilder.

String :

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;
}

String :

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;
}

Da append ist synchronized, StringBuffer hat Kopfleistung im Vergleich zu StrinbBuilder in Multi-Threading-Szenario. Solange Sie nicht Puffer unter mehreren Threads gemeinsam nutzen, verwenden StringBuilder, die aufgrund der Abwesenheit von synchronized in append Methoden schnell.

Hier ist die Leistung Tester für String vs String vs String . Schließlich gewann String Test durchführen. Siehe unten für Testcode und Ergebnis.

Code :

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");

  }

Execute Me auf ideone

Ergebnis :

100000 Iteration für einen einzelnen Text addiert

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

10000 Iteration für einen einzelnen Text addiert

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
  • String ist Thread-sicher aber ist String nicht Thread-sicher.
  • String ist schneller als String.
  • String synchronisiert während Stringbuilder nicht ist synchronisiert.

Jede Methode in String synchronisiert. folglich zu einem Zeitpunkt nur ein Thread erlaubt Stringbuffer-Objekt zu bedienen. Es erhöht die Wartezeit eines Threads und schafft Performance-Probleme Um dieses Problem zu überwinden, SUN Menschen Stringbuilder in Version 1.5 intoduced.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top