Frage Unterschied zwischen StringBuilder und StringBuffer


Was ist der Hauptunterschied zwischen? StringBuffer und StringBuilder? Gibt es irgendwelche Leistungsprobleme bei der Entscheidung über eine dieser?


1322
2017-12-10 04:34


Ursprung


Antworten:


StringBuffer ist synchronisiert, StringBuilder ist nicht.


1452
2017-12-10 04:36



StringBuilder ist schneller als StringBuffer weil es nicht ist 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);
        }
    }
}

EIN Testlauf gibt die Zahlen von 2241 ms zum StringBuffer vs 753 ms zum StringBuilder.


664
2018-05-05 09:15



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

Die Operationen sind "fast" gleich, aber die Verwendung synchronisierter Methoden in einem einzelnen Thread ist übertrieben.

Das ist ziemlich viel darüber.

Zitat aus StringBuilder-API:

Diese Klasse [StringBuilder] stellt eine API bereit, die mit StringBuffer kompatibel ist. aber ohne Garantie auf Synchronisation. Diese Klasse wurde als Ersatz für StringBuffer an den Stellen entwickelt, an denen der Zeichenfolgenpuffer von einem einzelnen Thread verwendet wurde (wie es normalerweise der Fall ist). Wo es möglich ist, wird empfohlen, diese Klasse gegenüber StringBuffer als bevorzugt zu verwenden Unter den meisten Implementierungen wird es schneller sein.

Also wurde es gemacht, um es zu ersetzen.

Das Gleiche ist passiert mit Vector und ArrayList.


228
2017-12-10 04:37



Aber musste man den deutlichen Unterschied mit Hilfe eines Beispiels herausfinden?

StringBuffer oder StringBuilder

Einfach benutzen StringBuilder es sei denn, Sie versuchen wirklich, einen Puffer zwischen Threads zu teilen. StringBuilder ist der unsynchronisierte (weniger Overhead = effizientere) jüngere Bruder des Originals synchronisiert StringBuffer Klasse.


151
2018-01-25 12:30



Zuerst sehen wir die Ähnlichkeiten: Sowohl StringBuilder als auch StringBuffer sind veränderbar. Das bedeutet, dass Sie den Inhalt derselben am gleichen Ort ändern können.

Unterschiede: StringBuffer ist änderbar und synchronisiert. Wobei als StringBuilder veränderbar, aber standardmäßig nicht synchronisiert ist.

Bedeutung von synchronisiert (Synchronisation): Wenn etwas synchronisiert ist, können mehrere Threads darauf zugreifen und es ohne Probleme oder Nebeneffekte ändern. StringBuffer ist synchronisiert, so dass Sie es mit mehreren Threads ohne Probleme verwenden können.

Welcher zu verwenden wann? StringBuilder: Wenn Sie eine Zeichenfolge benötigen, die geändert werden kann, und nur ein Thread auf sie zugreift und sie ändert. StringBuffer: Wenn Sie eine Zeichenfolge benötigen, die geändert werden kann, und mehrere Threads darauf zugreifen und sie ändern.

Hinweis : Verwenden Sie StringBuffer nicht unnötig, d. H. Verwenden Sie es nicht, wenn nur ein Thread es bearbeitet und darauf zugreift, da es viel Code zum Sperren und Entsperren für die Synchronisation enthält, was unnötigerweise CPU-Zeit in Anspruch nimmt. Verwenden Sie keine Sperren, wenn dies nicht erforderlich ist.


74
2017-12-11 07:11



In einzelnen Fäden, StringBuffer ist nicht wesentlich langsamer als StringBuilderdank JVM-Optimierungen. Und beim Multithreading können Sie einen StringBuilder nicht sicher verwenden.

Hier ist mein 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 :
Zeichenketten: 319740
Puffer: 23
Erbauer: 7!

Builder sind also schneller als Puffer und schneller als String-Verkettung. Jetzt verwenden wir ein Testamentsvollstrecker für mehrere Threads:

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 nehmen StringBuffers 157 ms für 100000 hängt an. Es ist nicht der gleiche Test, aber im Vergleich zu den vorherigen 37 ms können Sie davon ausgehen, dass StringBuffers angehängt sind langsamer mit Multithreading verwenden. Der Grund dafür ist, dass der JIT / Hotspot / Compiler / etwas Optimierungen macht, wenn er erkennt, dass es da ist Nein Notwendigkeit, Sperren zu überprüfen.

Aber Mit StringBuilder haben Sie java.lang.ArrayIndexOutOfBoundsException, weil ein gleichzeitiger Thread versucht, etwas hinzuzufügen, wo es nicht sollte.

Fazit ist, dass Sie StringBuffers nicht jagen müssen. Und wenn Sie Threads haben, denken Sie darüber nach, was sie tun, bevor Sie versuchen, ein paar Nanosekunden zu gewinnen.


42
2017-11-15 16:20



StringBuilder wurde in Java 1.5 eingeführt und funktioniert daher nicht mit früheren JVMs.

Von dem Javadocs:

Die StringBuilder-Klasse stellt eine API bereit, die mit StringBuffer kompatibel ist, aber keine Garantie für die Synchronisierung bietet. Diese Klasse wurde als Ersatz für StringBuffer an den Stellen entwickelt, an denen der Zeichenfolgenpuffer von einem einzelnen Thread verwendet wurde (wie es normalerweise der Fall ist). Wo es möglich ist, wird empfohlen, diese Klasse vor StringBuffer zu verwenden, da sie unter den meisten Implementierungen schneller ist.


37
2017-12-10 04:38



Ziemlich gute Frage

Hier sind die Unterschiede, ich habe festgestellt:

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.

Verbreitete Sache :-

Beide haben die gleichen Methoden mit den gleichen Signaturen. Beide sind veränderbar.


33
2018-04-11 20:25



StringBuilder ist nicht threadsicher. String Buffer ist. Mehr Info Hier.

EDIT: Wie für die Leistung, nach Hotspot tritt ein, StringBuilder ist der Gewinner. Bei kleinen Iterationen ist der Leistungsunterschied jedoch vernachlässigbar.


19
2017-12-10 04:41