StringBuilder e StringBuffer em Java
1. Visão geral
Neste breve artigo, veremos as semelhanças e diferenças entreStringBuilder eStringBuffer em Java.
Simplificando,StringBuilder foi introduzido no Java 1.5 como um substituto paraStringBuffer.
2. Semelhanças
TantoStringBuildereStringBuffer criam objetos que contêma mutable sequence of characters. Vamos ver como isso funciona e como se compara a uma classeString imutável:
String immutable = "abc";
immutable = immutable + "def";
Mesmo que pareça que estamos modificando o mesmo objeto anexando“def”, estamos criando um novo porque as instâncias deString não podem ser modificadas.
Ao usarStringBuffer ouStringBuilder,, podemos usar o métodoappend():
StringBuffer sb = new StringBuffer("abc");
sb.append("def");
Nesse caso, não havia novo objeto criado. Chamamos o métodoappend() na instânciasbe modificamos seu conteúdo. StringBuffereStringBuilder são objetos mutáveis.
3. Diferenças
StringBuffer é sincronizado e, portanto, thread-safe. StringBuilder é compatível com a APIStringBuffer, mas sem garantia de sincronização.
Por não ser uma implementação thread-safe, é mais rápida e é recomendado usá-la em lugares onde não há necessidade de thread safety.
3.1. atuação
Em pequenas iterações, a diferença de desempenho é insignificante. Vamos fazer um micro-benchmark rápido comJMH:
@State(Scope.Benchmark)
public static class MyState {
int iterations = 1000;
String initial = "abc";
String suffix = "def";
}
@Benchmark
public StringBuffer benchmarkStringBuffer(MyState state) {
StringBuffer stringBuffer = new StringBuffer(state.initial);
for (int i = 0; i < state.iterations; i++) {
stringBuffer.append(state.suffix);
}
return stringBuffer;
}
@Benchmark
public StringBuilder benchmarkStringBuilder(MyState state) {
StringBuilder stringBuilder = new StringBuilder(state.initial);
for (int i = 0; i < state.iterations; i++) {
stringBuilder.append(state.suffix);
}
return stringBuilder;
}
Usamos o modoThroughput padrão - ou seja, operações por unidade de tempo (maior pontuação é melhor), o que fornece:
Benchmark Mode Cnt Score Error Units
StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 86169.834 ± 972.477 ops/s
StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 91076.952 ± 2818.028 ops/s
Se aumentarmos o número de iterações de 1k para 1m, obtemos:
Benchmark Mode Cnt Score Error Units
StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 77.178 ± 0.898 ops/s
StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 85.769 ± 1.966 ops/s
No entanto, vamos ter em mente que este é um micro-benchmark, que pode ou não ter um impacto real no desempenho real de um aplicativo no mundo real.
4. Conclusões
Simplificando,StringBuffer é uma implementação thread-safe e, portanto, mais lenta do queStringBuilder.
Em programas single-threaded, podemos usarStringBuilder. Ainda assim,the performance gain of StringBuilder over StringBuffer may be too small to justify replacing it everywhere. É sempre uma boa ideia criar o perfil do aplicativo e entender suas características de desempenho de tempo de execução antes de fazer qualquer tipo de trabalho para substituir uma implementação por outra.
Finalmente, como sempre, o código usado durante a discussão pode ser encontradoover on GitHub.