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:

Spring Boot - Internationalization
Các chương trình minh họa sử dụng Cấu trúc điều khiển trong Java
Case-Insensitive String Matching in Java
Guide to java.util.Formatter
Lớp Arrarys trong Java (Arrays Utility Class)
The Modulo Operator in Java
Java Program to Find Location of a Point Placed in Three Dimensions Using K-D Trees
MyBatis with Spring
Spring MVC Content Negotiation
Java Program to Implement Triply Linked List
Hướng dẫn sử dụng Java Annotation
Java Program to Implement Lloyd’s Algorithm
Quick Intro to Spring Cloud Configuration
Recommended Package Structure of a Spring Boot Project
Tips for dealing with HTTP-related problems
Java Program to Represent Graph Using Incidence List
Jackson Unmarshalling JSON with Unknown Properties
Java Program to Give an Implementation of the Traditional Chinese Postman Problem
Java Program to Implement Gaussian Elimination Algorithm
Hướng dẫn sử dụng biểu thức chính quy (Regular Expression) trong Java
Java Program to Check whether Undirected Graph is Connected using DFS
Assert an Exception is Thrown in JUnit 4 and 5
Từ khóa this và super trong Java
Java – Convert File to InputStream
Java Program to add two large numbers using Linked List
Loại bỏ các phần tử trùng trong một ArrayList như thế nào?
Introduction to the Java NIO Selector
Lớp Collections trong Java (Collections Utility Class)
An Intro to Spring Cloud Zookeeper
Java Program to Decode a Message Encoded Using Playfair Cipher
Hướng dẫn Java Design Pattern – Singleton
Java Program to Test Using DFS Whether a Directed Graph is Weakly Connected or Not