StringBuffer versus StringBuilder
Author: Deron Eriksson
Description: This Java tutorial compares the StringBuffer and StringBuilder classes.
Tutorial created using: Windows Vista || JDK 1.6.0_11 || Eclipse JEE Ganymede SR1 (Eclipse 3.4.1)


The StringBuffer class has been around since the earliest days of JavaSW. Whereas a String is immutableW (can't change once it's been created), a StringBuffer is mutable. It can change in terms of length and content. StringBuffers are thread-safe, meaning that they have synchronized methods to control access so that only one thread can access a StringBuffer object's synchronized code at a time. Thus, StringBuffer objects are generally safe to use in a multi-threaded environment where multiple threads may be trying to access the same StringBuffer object at the same time.

The StringBuilder class was added to Java in version 1.5. The StringBuilder class is very similar to StringBuffer, except that its access is not synchronized so that it is not thread-safe. By not being synchronized, the performance of StringBuilder can be better than StringBuffer. Thus, if you are working in a single-threaded environment, using StringBuilder instead of StringBuffer may result in increased performance. This is also true of other situations such as a StringBuilder local variable (ie, a variable within a method) where only one thread will be accessing a StringBuilder object.

Let's do a simple test to compare the performance of StringBuilder and StringBuffer. The StringBuilderStringBuffer class below compares StringBuilder and StringBuffer. It times the appending of 5 million "a"s to a StringBuffer object and does the same for a StringBuilder object. It does this 10 times and records the total times. These totals are displayed in the console.

StringBuilderStringBuffer.java

package com.cakes;

import java.util.Date;

public class StringBuilderStringBuffer {

	public static void main(String[] args) {

		long totalStringBufferTest = 0;
		long totalStringBuilderTest = 0;
		for (int i = 0; i < 10; i++) {
			totalStringBufferTest += stringBufferTest();
			totalStringBuilderTest += stringBuilderTest();
		}

		System.out.println("Total time in milliseconds for StringBuffer test:" + totalStringBufferTest);
		System.out.println("Total time in milliseconds for StringBuilder test:" + totalStringBuilderTest);

	}

	public static long stringBufferTest() {
		Date start = new Date();
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < 5000000; i++) {
			stringBuffer.append("a");
		}
		Date end = new Date();
		long millis = end.getTime() - start.getTime();
		System.out.println("StringBuffer time in milliseconds:" + millis);
		return millis;
	}

	public static long stringBuilderTest() {
		Date start = new Date();
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < 5000000; i++) {
			stringBuilder.append("a");
		}
		Date end = new Date();
		long millis = end.getTime() - start.getTime();
		System.out.println("StringBuilder time in milliseconds:" + millis);
		return millis;
	}

}

The console output from the execution of StringBuilderStringBuffer is shown here. Notice that performance for StringBuilder is actually significantly better than StringBuffer. Thus, in single-threaded situations, it makes sense to use StringBuilder over StringBuffer.

Console Output

StringBuffer time in milliseconds:457
StringBuilder time in milliseconds:330
StringBuffer time in milliseconds:501
StringBuilder time in milliseconds:371
StringBuffer time in milliseconds:339
StringBuilder time in milliseconds:199
StringBuffer time in milliseconds:349
StringBuilder time in milliseconds:283
StringBuffer time in milliseconds:334
StringBuilder time in milliseconds:282
StringBuffer time in milliseconds:438
StringBuilder time in milliseconds:302
StringBuffer time in milliseconds:365
StringBuilder time in milliseconds:231
StringBuffer time in milliseconds:302
StringBuilder time in milliseconds:301
StringBuffer time in milliseconds:265
StringBuilder time in milliseconds:286
StringBuffer time in milliseconds:288
StringBuilder time in milliseconds:294
Total time in milliseconds for StringBuffer test:3638
Total time in milliseconds for StringBuilder test:2879