Monday, December 31, 2012

Difference Between StringBuilder and StringBuffer

Difference Between StringBuilder and StringBuffer

Both StringBuilder and StringBuffer are classes in Java that are used to manipulate strings dynamically. They share similar functionalities and inherit from the same abstract class, AbstractStringBuilder. However, their key difference lies in thread safety and performance.

Key Differences

  1. Thread Safety

    • StringBuffer:
      • Methods are synchronized, making it thread-safe.
      • Suitable for use in multi-threaded environments where multiple threads access the same instance.
    • StringBuilder:
      • Methods are not synchronized, meaning it is not thread-safe.
      • Offers better performance in single-threaded environments.
  2. Performance

    • Since StringBuffer uses synchronization, it incurs an overhead, leading to slower performance compared to StringBuilder.
    • StringBuilder is faster and should be the preferred choice when thread safety is not a concern.

public class App {
  
    private final static String[] words = new String[100000];
    static {
    for(int i = 0; i < words.length; i++) {
        words[i]= Integer.toString(i);
    }
    }
  
    /**
     * @param args
     */
    public static void main(String[] args) {
    for(int i = 0 ; i < 5; i++) {
            testStringAppend(new StringBuffer());
            testStringAppend(new StringBuilder());
    }
    }
  
    private static String testStringBuffer(StringBuffer sb) {   
    for(String word : words) {
        sb.append(word).append(";");
    }
    return sb.substring(0, sb.length() - 1);
    }
  
    private static String testStringBuilder(StringBuilder sb) { 
    for(String word : words) {
        sb.append(word).append(";");
    }
    return sb.substring(0, sb.length() - 1);
    }
  
    private static String testStringAppend(Object stringBuilder) {
    long timestamp = System.nanoTime(); 
    String string = null;   
    if(stringBuilder instanceof StringBuilder){
        string = testStringBuilder((StringBuilder)stringBuilder);
    } else if (stringBuilder instanceof StringBuffer) {
        string = testStringBuffer((StringBuffer)stringBuilder);
    } else {
        System.out.println("wrong type!");
        System.exit(1);
    }
  
    long elapsed = System.nanoTime() - timestamp;
    System.out.printf(stringBuilder.getClass().getName() + ": took %d ns per word%n", elapsed / words.length);
    return string;
    }
}
java.lang.StringBuffer: took 307 ns per word
java.lang.StringBuilder: took 172 ns per word
java.lang.StringBuffer: took 331 ns per word
java.lang.StringBuilder: took 59 ns per word
java.lang.StringBuffer: took 153 ns per word
java.lang.StringBuilder: took 56 ns per word
java.lang.StringBuffer: took 165 ns per word
java.lang.StringBuilder: took 105 ns per word
java.lang.StringBuffer: took 166 ns per word
java.lang.StringBuilder: took 53 ns per word

Analysis 

StringBuilder completes the operation much faster due to the absence of synchronization overhead. In scenarios where thread safety is unnecessary, StringBuilder is the optimal choice.