Diferença entre StringBuilder e StringBuffer
StringBuffer
e StringBuilder
?
Há algum problema de desempenho ao decidir sobre qualquer um destes?
30 answers
StringBuffer
está sincronizado, StringBuilder
não é.
StringBuilder
é mais rápido do que StringBuffer
porque não synchronized
.
Eis um teste de referência simples:
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);
}
}
}
A test run dá os números de 2241 ms
para StringBuffer
vs 753 ms
para StringBuilder
.
Basicamente, os métodos StringBuffer
são sincronizados enquanto StringBuilder
não são.
As operações são "quase" as mesmas, mas usar métodos sincronizados em um único tópico é exagero.
É mais ou menos isso.Citação de API StringBuilder:
Então foi feito para substituí-lo. O mesmo aconteceu comEsta classe [StringBuilder] fornece uma API compatível com StringBuffer, mas sem garantia de sincronização . Esta classe foi concebida para ser utilizada como um substituto StringBuffer em lugares onde o buffer de string estava sendo usado por um único thread (como é geralmente o caso). Sempre que possível, recomenda-se que esta classe seja usada em preferência a StringBuffer como será mais rápido sob a maioria das implementações.
Vector
e ArrayList
.
Mas precisava de ter a diferença clara com a ajuda de um exemplo?StringBuffer ou StringBuilder
basta usar StringBuilder
a menos que esteja mesmo a tentar partilhar um buffer entre tópicos. {[[0]} é o irmão mais novo da classe original sincronizada {[[2]}.
StringBuffer
veio primeiro. Sun estava preocupado com a correção sob todas as condições, então eles o sincronizaram para torná-lo seguro por precaução.
StringBuilder
veio mais tarde. A maioria dos usos de StringBuffer
eram de fio único e pagavam desnecessariamente o custo da sincronização.
Uma vez que {[[0]} é um substituição por gota para StringBuffer
sem a sincronização, não haveria diferenças entre quaisquer exemplos.
Se você está tentando compartilhar entre threads, você pode usar StringBuffer
, mas considere se a sincronização de nível superior é necessária, por exemplo talvez em vez de usar StringBuffer, você deve sincronizar os métodos que usam o StringBuilder.
Primeiro vamos ver as semelhanças: Tanto StringBuilder como StringBuffer são mutáveis. Isso significa que você pode mudar o conteúdo deles, com no mesmo local.
Diferenças : StringBuffer é mutável e sincronizado também. Onde como StringBuilder é mutável, mas não sincronizado por padrão.
Significado da Sincronização : Quando alguma coisa é sincronizada, então vários threads podem acessar, e modificá-lo sem qualquer problema ou efeito. O StringBuffer está sincronizado, por isso pode usá-lo com vários tópicos sem qualquer problema.
Qual usar quando? StringBuilder: quando você precisa de uma string, que pode ser modificável, e apenas uma thread está acessando e modificando-A. StringBuffer: quando você precisa de uma string, que pode ser modificável, e vários threads estão acessando e modificando-A.
Nota : não utilize o StringBuffer desnecessariamente, isto é, não o utilize se apenas um tópico estiver a modificar e acessá-lo porque ele tem muito código de bloqueio e desbloqueio para a sincronização que vai desnecessariamente tomar o tempo da CPU. Não use Fechaduras a menos que seja necessário.
Em linhas simples, o StringBuffer não é significativamente mais lento do que o StringBuilder, graças às optimizações da JVM. E em multithreading, você não pode usar com segurança um construtor de cordas.
Aqui está o meu teste.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));
}
Resultados:
cordas: 319740
Tampões de choque : 23
Construtor: 7 !
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);
}
}
Agora StringBuffers tome157 ms por 100000 aplicações. Não é o mesmo teste,mas em comparação com os 37 ms anteriores, você pode assumir com segurança que as aplicações de StringBuffers são mais lentas com o uso de multithreading . A razão é que o JIT / hotspot/compiler / something faz otimizações quando detecta que existe não necessidade de verificar Fechaduras.
Mas com o StringBuilder, tens java.idioma.Uma descrição indextosofboundsexception , porque um tópico concorrente tenta adicionar algo onde não devia.
A conclusão é que não tens de perseguir StringBuffers. E onde você tem fios, pense sobre o que eles estão fazendo, antes de tentar ganhar alguns nanossegundos.
StringBuilder foi introduzido no Java 1.5 por isso não vai funcionar com JVMs anteriores.
A classe StringBuilder fornece uma API compatível com StringBuffer, mas sem garantia de sincronização. Esta classe é projetada para ser usada como uma substituição drop-in para StringBuffer em lugares onde o buffer de string estava sendo usado por um único thread (como é geralmente o caso). Sempre que possível, recomenda-se a utilização preferencial desta classe to StringBuffer as it will be faster under most implementations.
Aqui estão as diferenças, eu notei:Boa Pergunta
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)
Construtor de cordas: -
StringBuilder is not synchronized
StringBuilder is not thread-safe
StringBuilder performance is better than StringBuffer.
Coisa comum: -
Ambos têm os mesmos métodos com as mesmas assinaturas. Ambos são mutáveis.
StringBuilder
e são quase iguais. A diferença é que StringBuffer
está sincronizado e StringBuilder
não está. Embora, StringBuilder
Seja mais rápido que StringBuffer
, a diferença de desempenho é muito pequena. StringBuilder
é um substituto do sol de StringBuffer
. Apenas evita a sincronização de todos os métodos públicos. Ao invés disso, sua funcionalidade é a mesma.
Exemplo de boa utilização:
Se o seu texto vai mudar e é usado por vários tópicos, então é melhor usar StringBuffer
. Se seu texto vai mudar, mas é usado por um único tópico, então use StringBuilder
.
StringBuffer
StringBuffer é mutável significa que se pode mudar o valor do objecto . O objeto criado através do StringBuffer é armazenado no heap . StringBuffer tem os mesmos métodos que o StringBuilder , mas cada método em StringBuffer é sincronizado que é StringBuffer é thread safe .
Por causa disso, não permite que dois threads acessem simultaneamente o mesmo método . Cada método pode ser acessado por um fio de cada vez .
Mas ser thread safe também tem desvantagens como o desempenho do StringBuffer hits devido à propriedade thread safe . Assim, StringBuilder é mais rápido do que o StringBuffer ao chamar os mesmos métodos de cada classe.
O valor do StringBuffer pode ser alterado, significa que pode ser atribuído ao novo valor . Hoje é uma questão de entrevista mais comum, as diferenças entre as classes acima. String Buffer pode ser convertido para a string usando toString () metodo.
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
Construtor de cordas
StringBuilder é o mesmo que o StringBuffer, ou seja, armazena o objecto em heap e também pode ser modificado . A principal diferença entre o StringBuffer e StringBuilder é que StringBuilder também não é thread safe. StringBuilder é rápido como não é 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
StringBuffer
- sincronizado por threadsafe Por isso, devagar. -
StringBuilder
- introduzido no Java 5.0
- assíncrono, logo rápido e eficiente
- O Utilizador precisa de sincronizá-lo explicitamente, se quiser
- pode substituí-lo
StringBuilder
sem qualquer outra alteração
String
é imutável.
StringBuffer
é mutável e sincronizado.
StringBuilder
é também mutável, mas não está sincronizado.
O javadoc explica a diferença:
Esta classe fornece uma API compatível com StringBuffer, mas sem garantia de sincronização. Esta classe é projetada para ser usada como uma substituição drop-in para StringBuffer em lugares onde o buffer de string estava sendo usado por um único thread (como é geralmente o caso). Sempre que possível, recomenda-se que esta classe seja usada em preferência a StringBuffer, pois será mais rápido sob a maioria das implementações.
StringBuilder
(introduzido em Java 5) é idêntico a StringBuffer
, exceto que seus métodos não são sincronizados. Isto significa que tem melhor desempenho do que este último, mas a desvantagem é que ele não é thread-safe.
Leia tutorial para mais detalhes.
Aqui você tem mais idéia sobre o custo de sincronizar
Vejamos programaticamente quanto Construtor de cordas é mais rápido do que StringBuffer
public class Test{
public static void main(String[] args){
long startTime = System.currentTimeMillis();
StringBuffer sb = new StringBuffer("Yasir");
for (int i=0; i<10000; i++){
sb.append("Shabbir");
}
System.out.println("Time taken by StringBuffer: " + (System.currentTimeMillis() - startTime) + "ms");
startTime = System.currentTimeMillis();
StringBuilder sb2 = new StringBuilder("Yasir");
for (int i=0; i<10000; i++){
sb2.append("Shabbir");
}
System.out.println("Time taken by StringBuilder: " + (System.currentTimeMillis() - startTime) + "ms");
}
}
Resultado
Tempo tomado por StringBuffer: 16ms
Tempo tomado pelo construtor de StringBuilder: 0ms
UM programa simples que ilustra a diferença entre o StringBuffer e o 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");
}
}
}
Melhor usar StringBuilder uma vez que não é sincronizado e, portanto, melhor desempenho. StringBuilder é uma substituição do StringBuffer mais antigo.
StringBuffer
está sincronizado, mas StringBuilder
não está. Como resultado, StringBuilder
é mais rápido que StringBuffer
.
StringBuffer é mutável. Pode mudar em termos de comprimento e conteúdo. StringBuffers são thread-safe, O que significa que eles têm métodos sincronizados para controlar o acesso de modo que apenas um thread pode acessar o código sincronizado de um objeto StringBuffer de cada vez. Assim, objetos StringBuffer são geralmente seguros de usar em um ambiente multi-threaded onde vários threads podem estar tentando acessar o mesmo objeto StringBuffer ao mesmo tempo.
StringBuilder O A classe StringBuilder é muito semelhante à StringBuffer, exceto que seu acesso não é sincronizado de modo que não é thread-safe. Ao não ser sincronizado, o desempenho de StringBuilder pode ser melhor do que StringBuffer. Assim, se você está trabalhando em um ambiente de simples threaded, usando StringBuilder em vez de StringBuffer pode resultar em maior desempenho. Isto também é verdade para outras situações, como uma variável local StringBuilder (ou seja, uma variável dentro de um método) onde apenas um tópico irá estar a aceder a um objecto de construção de cordas.
StringBuffer
StringBuffer é mutável significa que se pode mudar o valor do objecto . O objeto criado através do StringBuffer é armazenado no heap . StringBuffer tem os mesmos métodos que o StringBuilder , mas cada método em StringBuffer é sincronizado que é StringBuffer é thread safe .
Construtor de cordas
StringBuilder é o mesmo que o StringBuffer, ou seja, armazena o objecto em heap e também pode ser modificado . Principal a diferença entre o StringBuffer e o StringBuilder é que StringBuilder não é thread safe. StringBuilder é rápido como não é thread safe .
StringBuffer:
- Linhas Múltiplas
- sincronizado
- lento que o Construtor de cordas
Construtor de cordas
- Fio Simples
- Não Sincronizado
- mais rápido do que nunca
Construtor De Textos :
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);
Recomenda-se a utilização de StringBuilder sempre que possível porque é mais rápido do que StringBuffer. No entanto, se a segurança do rosca é necessária, a melhor opção é objetos StringBuffer.
O StringBuffer é usado para guardar as cadeias de caracteres que serão alteradas (os objectos de texto não podem ser alterados). Expande-se automaticamente conforme necessário. Classes relacionadas: String, CharSequence.
StringBuilder foi adicionado no Java 5. É idêntico em todos os aspectos ao StringBuffer, exceto que ele não é sincronizado, o que significa que se vários threads estão acessando ao mesmo tempo, pode haver problemas. Para programas simples, o caso mais comum, evitando a sobrecarga de a sincronização faz com que o StringBuilder seja um pouco mais rápido.
Uma vez que StringBuffer
está sincronizado, precisa de algum esforço extra, Portanto baseado na perfeição, é um pouco lento que StringBuilder
.
String é um objecto imutável, o que significa que o valor não pode ser alterado quando o StringBuffer é mutável.
O 'StringBuffer' está sincronizado, daí o 'thread safe' onde o 'StringBuilder' não é e é adequado apenas para instâncias simples.
A principal diferença é {[0] } é sincronizada mas StringBuilder
não é.Se você precisa usar mais de um fio , então StringBuffer é recomendado.Mas, de acordo com a velocidade de execução StringBuilder
é mais rápido que {[[0]}, porque não é sincronizado .
Verifique os internos do método de anexação sincronizado de StringBuffer
e o método de anexação não sincronizado de StringBuilder
.
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;
}
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;
}
Uma vez que a apend é synchronized
, StringBuffer
tem desempenho superior em comparação com StrinbBuilder
em cenário de multi-threading. Desde que não esteja a partilhar o buffer entre vários tópicos, use StringBuilder
, que é rápido devido à ausência de synchronized
nos métodos de anexação.
Este link fará você entender os conceitos não só de {[[0]} e StringBuffer
mas também a sua Associação e diferença com String
classe. Isto vai fazer você entender quando usar que Classe.
http://www.acquireandinspire.org/2013/01/string-string-builder-string-buffer.html