Domanda

Qual è la differenza principale tra StringBuffer E StringBuilder?Ci sono problemi di prestazioni quando si decide su uno di questi?

È stato utile?

Soluzione

StringBuffer è sincronizzato, StringBuilder non è.

Altri suggerimenti

StringBuilder è più veloce di StringBuffer perché non è synchronized .

Ecco un semplice test di benchmark:

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

Un prova di funzionamento dà il numero di 2241 ms per 753 ms vs <=> per <=> .

Fondamentalmente, StringBuffer metodi sono sincronizzati mentre StringBuilder non sono.

Le operazioni sono "quasi" lo stesso, ma usando metodi sincronizzati in un singolo filo è eccessivo.

Questo è più o meno su di esso.

StringBuilder API :

  

Questa classe [StringBuilder] fornisce un API compatibile con StringBuffer, ma senza alcuna garanzia di sincronizzazione . Questa classe è progettato per l'uso come sostituzione drop-in per StringBuffer in luoghi dove il buffer di stringa veniva usato da un unico filo (come è generalmente il caso). Ove possibile, si raccomanda che questa classe essere usato di preferenza per StringBuffer come sarà più veloce nella maggior parte delle implementazioni.

Così è stato fatto per sostituirlo.

Lo stesso è accaduto con Vector e ArrayList.

  

Ma necessario per ottenere la netta differenza con l'aiuto di un esempio?

     

StringBuffer o StringBuilder

Basta usare StringBuilder meno che davvero sta cercando di condividere un cuscinetto tra i thread. StringBuffer è il non sincronizzato (meno overhead = più efficiente) fratello minore del <=> classe sincronizzato originale.

<=> è venuto prima. Sun si occupava di correttezza in tutte le condizioni, in modo che ha reso sincronizzato per renderlo thread-safe per ogni evenienza.

<=> è venuto dopo. La maggior parte degli usi di <=> erano single-thread e inutilmente pagare il costo della sincronizzazione.

Poiché <=> è un rimpiazzo per <=> senza la sincronizzazione, non ci sarebbero differenze tra gli esempi.

Se sono cercare di condividere tra i thread, è possibile utilizzare <=>, ma considerare se la sincronizzazione di livello superiore è necessario, ad esempio, forse invece di usare StringBuffer, si dovrebbe sincronizzare i metodi che utilizzano lo StringBuilder.

Per prima cosa vediamo il analogie:Sia StringBuilder che StringBuffer sono modificabili.Ciò significa che puoi modificarne il contenuto, nella stessa posizione.

Differenze:Anche StringBuffer è mutabile e sincronizzato.Dove StringBuilder è mutabile ma non sincronizzato per impostazione predefinita.

Significato di sincronizzato (sincronizzazione):Quando qualcosa è sincronizzato, più thread possono accedervi e modificarlo senza alcun problema o effetto collaterale.StringBuffer è sincronizzato, quindi puoi usarlo con più thread senza alcun problema.

Quale usare quando?StringBuilder:Quando hai bisogno di una stringa, che può essere modificabile, e solo un thread accede e la modifica.StringBuffer:Quando è necessaria una stringa, che può essere modificabile, e più thread accedono e la modificano.

Nota :Non utilizzare StringBuffer inutilmente, ovvero non utilizzarlo se solo un thread lo sta modificando e accedendo perché contiene molto codice di blocco e sblocco per la sincronizzazione che occuperà inutilmente tempo della CPU.Non utilizzare i lucchetti a meno che non sia necessario.

In singoli fili, StringBuffer non è significativamente più lento di StringBuilder , grazie a ottimizzazioni JVM. E in multithreading, non è possibile utilizzare in modo sicuro uno StringBuilder.

Ecco la mia prova (non un punto di riferimento, solo una prova):

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

Risultati:
stringhe: 319740
Buffer: 23
Costruttore: 7

Così Costruttori sono più veloce di buffer e modo più veloce di stringhe concatenazione. Ora usiamo un Executor per più thread:

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

Ora StringBuffers prendere 157 ms per 100000 accodamento. Non è lo stesso test, ma rispetto ai precedenti 37 ms, si può tranquillamente supporre che i StringBuffers accodamento sono più lenti con l'utilizzo multithreading . La ragione è che il JIT / hotspot / compilatore / qualcosa rende ottimizzazioni quando rileva che non v'è non necessità di controllare le serrature.

Ma con StringBuilder, avete java.lang.ArrayIndexOutOfBoundsException , perché un filo concomitante tenta di aggiungere qualcosa dove non dovrebbe.

conclusione è che non c'è bisogno di inseguire StringBuffers. E dove si hanno le discussioni, pensare a quello che stanno facendo, prima di cercare di guadagnare pochi nanosecondi.

StringBuilder è stato introdotto in Java 1.5 in modo che non funziona con JVM precedenti.

Javadocs :

  

classe StringBuilder fornisce un API compatibile con StringBuffer, ma senza alcuna garanzia di sincronizzazione. Questa classe è progettato per l'uso come sostituzione drop-in per StringBuffer in luoghi dove il buffer di stringa veniva usato da un unico filo (come è generalmente il caso). Ove possibile, si raccomanda che questa classe essere usato di preferenza per StringBuffer in quanto sarà più veloce nella maggior parte delle implementazioni.

  

Pretty Good domanda

Qui ci sono le differenze, ho notato:

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.

cosa comune: -

  

Entrambi hanno stessi metodi con le stesse firme. Entrambi sono mutabili.

StringBuilder non è thread-safe. String Buffer è. Maggiori informazioni href="http://www.java-tips.org/java-se-tips/java.lang/difference-between-string-stringbuffer-and-stringbu.html" qui .

EDIT: Per quanto riguarda le prestazioni, dopo hotspot calci, StringBuilder è il vincitore. Tuttavia, per le piccole iterazioni, la differenza di prestazioni è trascurabile.

StringBuilder e StringBuffer sono quasi la stessa cosa. La differenza è che <=> è sincronizzato e <=> non è. Anche se, è più veloce di <=> <=>, la differenza di prestazioni è molto poco. <=> è la sostituzione di un sole di <=>. E 'appena evita la sincronizzazione di tutti i metodi pubblici. Invece di questo, la loro funzionalità è la stessa.

Esempio di buona utilizzo:

Se il testo sta per cambiare e viene utilizzato da più thread, allora è meglio usare <=>. Se il testo sta per cambiare, ma è utilizzato da un unico filo, quindi utilizzare <=>.

StringBuffer

  • sincronizzato quindi threadsafe
  • thread-safe quindi lento

StringBuilder

  • Introdotto in Java 5.0
  • Asynchronous quindi veloce ed efficiente
  • L'utente deve esplicitamente per sincronizzarlo, se vuole
  • È possibile sostituirlo con <=> senza alcun altro cambiamento

StringBuffer

StringBuffer è mutevole significa che si può modificare il valore dell'oggetto. L'oggetto creato attraverso StringBuffer è memorizzato nel mucchio. StringBuffer ha gli stessi metodi StringBuilder, ma ciascun metodo StringBuffer è sincronizzato che è StringBuffer è sicuro thread.

a causa di questo non consente due thread di accedere simultaneamente lo stesso metodo. Ogni metodo può essere letta da un thread alla volta.

Ma essere thread-safe ha svantaggi troppo come le prestazioni del StringBuffer colpisce a causa di infilare proprietà al sicuro. Così StringBuilder è più veloce della StringBuffer quando si chiama gli stessi metodi di ciascuna classe.

valore StringBuffer può essere cambiato, significa che può essere assegnato al nuovo valore. Al giorno d'oggi la sua una questione intervista più comune, le differenze tra le classi di cui sopra. String buffer può essere convertito la stringa utilizzando metodo toString ().

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 è stesso StringBuffer, cioè memorizza l'oggetto in mucchio e può anche essere modificato. La differenza principale tra la StringBuffer e StringBuilder è che StringBuilder è anche non thread-safe. StringBuilder è veloce in quanto non è thread-safe.

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

 entrare descrizione dell'immagine qui

Resource: stringa Vs StringBuffer Vs StringBuilder

String è un immutabile.

StringBuffer è un mutevole e sincronizzato.

StringBuilder è anche mutevole ma non è sincronizzata.

Un semplice programma che illustra la differenza tra StringBuffer e StringBuilder:

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

    }
}

Un miglior uso StringBuilder dal momento che non è sincronizzato e loro migliori prestazioni. StringBuilder è una sostituzione drop-in della vecchia StringBuffer.

StringBuffer è sincronizzato, ma StringBuilder non è. Di conseguenza, è più veloce di <=> <=>.

StringBuffer è mutevole. Può cambiare in termini di lunghezza e contenuti. StringBuffers sono thread-safe, il che significa che essi hanno sincronizzati metodi per controllare l'accesso in modo che solo un thread può accedere al codice sincronizzato di un oggetto StringBuffer alla volta. Così, oggetti StringBuffer sono generalmente sicura da utilizzare in un ambiente multi-thread in cui più thread può tentare di accedere allo stesso oggetto StringBuffer allo stesso tempo.

StringBuilder La classe StringBuilder è molto simile a StringBuffer, salvo che l'accesso non è sincronizzato in modo che non è thread-safe. Da non essere sincronizzato, le prestazioni di StringBuilder può essere meglio di StringBuffer. Pertanto, se si lavora in un ambiente a thread singolo, utilizzando StringBuilder anziché StringBuffer può risultare in un aumento delle prestazioni. Ciò vale anche per altre situazioni come una variabile locale StringBuilder (cioè, una variabile all'interno di un metodo) dove solo un thread sarà accede a un oggetto StringBuilder.

StringBuffer:

  • Multi-Thread
  • sincronizzato
  • lento di StringBuilder

StringBuilder

  • single-thread
  • Non-sincronizzato
  • Più veloce che mai Stringa

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

Si raccomanda di utilizzare StringBuilder quando possibile, perché è più veloce di StringBuffer. Tuttavia, se è necessaria la sicurezza del filo, la soluzione migliore è oggetto StringBuffer.

StringBuffer viene utilizzato per memorizzare le stringhe di caratteri che verranno modificati (oggetti String non può essere modificato). Si espande automaticamente secondo necessità. Lezioni collegate:. String, CharSequence

StringBuilder è stato aggiunto in Java 5. È identico in tutti gli aspetti a StringBuffer tranne che non è sincronizzato, il che significa che se più thread accedono allo stesso tempo, ci potrebbero essere problemi. Per i programmi a thread singolo, il caso più comune, evitando il sovraccarico di sincronizzazione rende lo StringBuilder molto leggermente più veloce.

Non ci sono differenze fondamentali tra StringBuilder e StringBuffer, esistono solo poche differenze tra di loro. In StringBuffer sono sincronizzati i metodi. Ciò significa che in un momento solo un thread può operare su di essi. Se ci sono più di un thread poi il secondo filo dovrà aspettare il primo a finire e la terza si dovrà attendere per il primo e secondo per terminare e così via. Questo rende il processo molto lento e quindi le prestazioni in caso di StringBuffer è basso.

D'altro canto è StringBuilder non sincronizzati. Ciò significa che in un momento più thread possono operare sullo stesso oggetto StrinBuilder allo stesso tempo. Questo rende il processo molto veloce e quindi le prestazioni di StringBuilder è elevata.

Da StringBuffer è sincronizzato, è necessario un certo sforzo supplementare, quindi in base alle prestazioni, è un po 'lento di StringBuilder.

String è un oggetto immutabile che significa che il valore non può essere modificato dove come StringBuffer è mutevole.

Lo StringBuffer è sincronizzato quindi infilare sicuro dove come StringBuilder non e adatto è per istanze unico singolo filettati.

La differenza principale è StringBuffer è sincronizzata ma StringBuilder è not.If è necessario utilizzare più di un thread, quindi StringBuffer è recommended.But, come per la velocità di esecuzione <=> è più veloce di <=> , perché la sua non sincronizzati.

Controlla la struttura interna di metodo Append sincronizzato di StringBuffer e non sincronizzata metodo Append di 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;
}

Dal momento che append è synchronized, StrinbBuilder ha sovraccarico di prestazioni rispetto al <=> nello scenario multi-threading. Finchè non condivide tampone tra più thread, utilizzare <=>, che è veloce dovuta all'assenza di <=> nei metodi di aggiunta.

Ecco il risultato di test delle prestazioni per String vs StringBuffer vs StringBuilder . Infine, StringBuilder ha vinto il test. Vedi sotto per il codice di prova e il risultato.

Codice :

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

  }

Esegui Me on Ideone

Risultato :

100000 iterazione per l'aggiunta di un testo unico

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

10000 iterazione per l'aggiunta di un testo unico

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
  • StringBuffer è thread-safe, ma StringBuilder non è thread-safe.
  • StringBuilder è più veloce di StringBuffer.
  • StringBuffer è sincronizzato, mentre non è StringBuilder sincronizzato.

Ogni metodo presente in StringBuffer è sincronizzato. quindi in un tempo solo un thread può operare oggetto StringBuffer. Aumenta il tempo di attesa di un filo e crea problemi di prestazioni per ovviare a questo problema SUN Persone intoduced StringBuilder in versione 1.5.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top