StringBuilder vs StringBuffer in Java

1. Overview

In this short article, we’re going to look at similarities and differences between StringBuilder and StringBuffer in Java.

Simply put, StringBuilder was introduced in Java 1.5 as a replacement for StringBuffer.

2. Similarities

Both StringBuilder and StringBuffer create objects that hold a mutable sequence of characters. Let’s see how this works, and how it compares to an immutable String class:

String immutable = "abc";
immutable = immutable + "def";

Even though it may look like that we’re modifying the same object by appending “def”, we are creating a new one because String instances can’t be modified.

When using either StringBuffer or StringBuilder, we can use the append() method:

StringBuffer sb = new StringBuffer("abc");
sb.append("def");

In this case, there was no new object created. We have called the append() method on sb instance and modified its content. StringBuffer and StringBuilder are mutable objects.

3. Differences

StringBuffer is synchronized and therefore thread-safe. StringBuilder is compatible with StringBuffer API but with no guarantee of synchronization.

Because it’s not a thread-safe implementation, it is faster and it is recommended to use it in places where there’s no need for thread safety.

3.1. Performance

In small iterations, the performance difference is insignificant. Let’s do a quick micro-benchmark with JMH:

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

We have used the default Throughput mode – i.e. operations per unit of time (higher score is better), which gives:

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

If we increase the number of iterations from 1k to 1m then we get:

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

However, let’s bear in mind that this is a micro-benchmark, which may or may not have a real impact on the actual, real-world performance of an application.

4. Conclusions

Simply put, the StringBuffer is a thread-safe implementation and therefore slower than the StringBuilder.

In single-threaded programs, we can take of the StringBuilder. Yet, the performance gain of StringBuilder over StringBuffer may be too small to justify replacing it everywhere. It’s always a good idea to profile the application and understand its runtime performance characteristics before doing any kind of work to replace one implementation with another.

Finally, as always, the code used during the discussion can be found over on GitHub.

Related posts:

Hướng dẫn Java Design Pattern – Bridge
Java Program to Implement D-ary-Heap
LinkedList trong java
Semaphore trong Java
Logout in an OAuth Secured Application
Java – Reader to Byte Array
Java Program to Create a Minimal Set of All Edges Whose Addition will Convert it to a Strongly Conne...
Java Program to Use Boruvka’s Algorithm to Find the Minimum Spanning Tree
Java Program to Perform Addition Operation Using Bitwise Operators
Java Program to Implement the Hill Cypher
Java Program to Implement Gaussian Elimination Algorithm
Java Program to Generate Date Between Given Range
Simple Single Sign-On with Spring Security OAuth2
String Processing with Apache Commons Lang 3
@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll
Java Program to find the maximum subarray sum using Binary Search approach
Java Program to Implement Singly Linked List
Java Program to Solve a Matching Problem for a Given Specific Case
Spring Boot - Bootstrapping
Java Program to Implement Attribute API
Java Program to Implement Bubble Sort
JWT – Token-based Authentication trong Jersey 2.x
Java Program to Check if it is a Sparse Matrix
Java – File to Reader
Guide to Dynamic Tests in Junit 5
Java Program to Implement Bloom Filter
Java Program to Solve Travelling Salesman Problem for Unweighted Graph
Spring Boot - Tracing Micro Service Logs
Java Program to Check whether Undirected Graph is Connected using BFS
Java Program to Implement Cartesian Tree
Java Program to Implement Ternary Heap
Hướng dẫn Java Design Pattern – Intercepting Filter