1732 Stimmen

Unterschied zwischen StringBuilder und StringBuffer

Was ist der Hauptunterschied zwischen StringBuffer y StringBuilder ? Gibt es irgendwelche Leistungsprobleme, wenn man sich für eines dieser Produkte entscheidet?

59voto

Nicolas Zozol Punkte 6855

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

Hier ist mein Test (kein Benchmark, nur ein 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:
Streicher: 319740
Puffer : 23
Erbauer : 7 !

Builder sind also schneller als Puffer und VIEL schneller als die Verkettung von Zeichenketten. Verwenden wir nun einen 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 Anhänge. Es ist nicht derselbe Test, aber im Vergleich zu den vorherigen 37 ms können Sie sicher davon ausgehen, dass StringBuffers appends sind langsamer bei Multithreading Verwendung . Der Grund dafür ist, dass der JIT/Hotspot/Compiler/etwas Optimierungen vornimmt, wenn er feststellt, dass es eine keine Notwendigkeit der Überprüfung von Schlössern.

Pero mit StringBuilder, haben Sie java.lang.ArrayIndexOutOfBoundsException weil ein gleichzeitiger Thread versucht, etwas hinzuzufügen, was er nicht sollte.

Die Schlussfolgerung ist, dass man StringBuffers nicht jagen muss. Und wenn Sie Threads haben, denken Sie darüber nach, was sie tun, bevor Sie versuchen, ein paar Nanosekunden zu gewinnen.

42voto

Marc Novakowski Punkte 43303

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

Von der Javadocs :

Die Klasse StringBuilder bietet eine API, die mit StringBuffer kompatibel ist, aber keine Garantie für die Synchronisierung bietet. Diese Klasse ist als Ersatz für StringBuffer gedacht, wenn der String-Buffer von einem einzigen Thread verwendet wird (was im Allgemeinen der Fall ist). Wenn möglich, wird empfohlen, dass diese Klasse anstelle von StringBuffer verwendet wird, da sie bei den meisten Implementierungen schneller ist.

37voto

Sireesh Yarlagadda Punkte 11586

Ziemlich gute Frage

Hier sind die Unterschiede, die ich festgestellt habe:

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.

Gemeinsame Sache :-

Beide haben dieselben Methoden mit denselben Signaturen. Beide sind veränderbar.

27voto

JRomio Punkte 2067

StringBuffer

  • Synchronisiert und daher fadensicher
  • Fadensicher und daher langsam

StringBuilder

  • Eingeführt in Java 5.0
  • Asynchron, daher schnell und effizient
  • Der Benutzer muss sie explizit synchronisieren, wenn er will
  • Sie können ihn ersetzen durch StringBuffer ohne weitere Änderungen

25voto

Afee Punkte 2639

StringBuffer

StringBuffer ist veränderbar, d.h. man kann den Wert des Objekts ändern. Das durch StringBuffer erzeugte Objekt wird im Heap gespeichert. StringBuffer hat die gleichen Methoden wie der StringBuilder, aber jede Methode in StringBuffer ist synchronisiert, d.h. StringBuffer ist thread safe.

Deshalb ist es nicht möglich, dass zwei Threads gleichzeitig auf dieselbe Methode zugreifen. Auf jede Methode kann jeweils nur von einem Thread zugegriffen werden.

Die Threadsicherheit hat jedoch auch Nachteile, da die Leistung des StringBuffers aufgrund der Threadsicherheitseigenschaft leidet. Daher ist der StringBuilder schneller als der StringBuffer, wenn die gleichen Methoden der beiden Klassen aufgerufen werden.

StringBuffer-Wert kann geändert werden, d.h. er kann dem neuen Wert zugewiesen werden. Heutzutage ist es eine häufig gestellte Frage im Interview, die Unterschiede zwischen den oben genannten Klassen. String Buffer kann in eine Zeichenkette umgewandelt werden, indem man die toString() Methode umgewandelt werden.

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 ist das gleiche wie die StringBuffer, das heißt, es speichert das Objekt in Heap und es kann auch geändert werden. Der Hauptunterschied zwischen dem StringBuffer und dem StringBuilder besteht darin, dass der StringBuilder ebenfalls nicht thread-sicher ist. Der StringBuilder ist schnell, da er nicht thread-sicher ist.

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

enter image description here

Ressource: String Vs StringBuffer Vs StringBuilder

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X