Saturday, 29 August 2015

Difference between StringBuilder and StringBuffer in Java

Background

In Java String class is immutable. So each concatenation or substring operation yields a new String.

Yes we all have heard String concatenation is bad to create long Strings. Concatenating large number of String literals will fill up the permgen area (where String pool resides) faster. One of the reason why SLF4J is preferred over LOG4J  . Incase you need to concatenate String literals you can use StringBuilder or StringBuffer instance instead. You can just keep appending your String literals to this instance and finally call toString() to get a single String instance. In this post we will see the difference between StringBuilder and StringBuffer.

StringBuilder and StringBuffer in Java

Their usages are quite simple.

        StringBuffer sBuffer = new StringBuffer("abc");
        sBuffer.append("pqr");
        System.out.println(sBuffer.toString());
        
        StringBuilder sBuilder = new StringBuilder("abc");
        sBuilder.append("pqr");
        System.out.println(sBuilder.toString());



As you can see the usage is similar but their difference is very important which we will see now. Just a note no new strings are created when append is called. Internally an array is maintained and String characters are appended to it.

Difference between StringBuilder and StringBuffer in Java

The most important difference between them is 
  • StringBuffer is synchronized, StringBuilder is not.
Hence unless you have a multithreaded scenario to deal with always go for  StringBuilder and not StringBuffer. Even if you have multithread situation you can use a synchronized block around StringBuilder.

 You can say - "StringBuilder is intended as a drop in replacement for StringBuffer where synchronisation is not required"

Quoting the API docs for StringBuilder -

"A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations."

A simple test for performance would be -

public class HelloWorld {
    public static void main(String args[]) throws IOException
    {        
        int limit = 1000000;
        long currTime;
        long timeTaken;

        {
            StringBuffer sb = new StringBuffer();
            currTime = System.currentTimeMillis();
            for (int i = limit; i --> 0 ;) {
                sb.append("");
            }
            timeTaken = System.currentTimeMillis() - currTime;
            System.out.println("StringBuffer Time : " + timeTaken);
        }
        {
            StringBuilder sb = new StringBuilder();
            currTime = System.currentTimeMillis();
            for (int i = limit; i --> 0 ;) {
                sb.append("");
            }
            timeTaken = System.currentTimeMillis() - currTime;
            System.out.println("StringBuilder Time : " + timeTaken);
        }   
    }
}


and this prints (one execution) -

StringBuffer Time : 29
StringBuilder Time : 6



Summary

So to summarize always use StringBuilder and not StringBuffer.

Related Links


No comments:

Post a Comment

t> UA-39527780-1 back to top