Monday, November 19, 2012

Compare performace of String and StringBuilder


As we know java.lang.String is an immutable class. When we want to combine Strings, a lot of new Strings will be created before we get the last result. In some case as reading long text files or retrieving and concatenating big text fields from DB, we should consider to use StringBuilder instead of String. We will see how we could improve performance.

String – an immutable class

Immutable classes offer safe threads when we use them. However, there is a disadvantage of this type of classes is the number of existing objects. Every time we invoke methods to change states of immutable objects, we truly create new objects. Let we see an example:
          String message = "Java";
          message += " is a programming";
          message += "language.";
And we will have message = “Java is a programming language.”. The question is: How many String objects do we have after running this code? Three? Or four? The answer is five Strings: 3 obviously Strings “Java”, “ is a programming”, and “ language”; the result String “Java is a programming language.”; and another one is “Java is a programming”. The “+” operation or the concat() method of String does copy contents of original Strings to make a new String.
When the frequency to combine Strings is large, we will get abysmal performance.
StringBuilder is a mutable sequence of characters. StringBuilder is not synchronized as StringBuffer. The main operations of StringBuilder are convert() and append(). We should use StringBuilder when we need to concatenate Strings.

Compare performance by using String and StringBuilder

My computer uses Window 7 with Core i3 2.27GHz CPU and 4Gb Ram. I downloaded from the Internet one text file having 10800 lines. We will see the simple code to read this text file:

public class Test {
     public static void main(String[] args) {
          long start = System.currentTimeMillis();
          readFile("sample.txt");
          long stop = System.currentTimeMillis();
          System.out.println("Running time: " + (stop - start) + " ms");
     }

     public static String readFile(String filename) {
          String content = "";
          try {
               File file = new File(filename);
              FileReader fr;
              fr = new FileReader(file);
              BufferedReader br = new BufferedReader(fr);
              String line = "";
              while ((line = br.readLine()) != null) {
                   content += line;
              }
              br.close();
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
          return content;
     }
}
When I run this code on my laptop, the output was “Running time: 16967 ms”, near by 17 seconds. Now let we change a bit to use StringBuilder:

public class Test {
     public static void main(String[] args) {
          long start = System.currentTimeMillis();
          readFile("sample.txt");
          long stop = System.currentTimeMillis();
          System.out.println("Running time: " + (stop - start) + " ms");
     }

     public static String readFile(String filename) {
          StringBuilder content = new StringBuilder();
          try {
              File file = new File(filename);
              FileReader fr;
              fr = new FileReader(file);
              BufferedReader br = new BufferedReader(fr);
              String line = "";
              while ((line = br.readLine()) != null) {
                   content.append(line);
              }
              br.close();
          } catch (FileNotFoundException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }

          return content.toString();
     }
}
Running this code, I got the output: “Running time: 24 ms”, faster than 700 times! Therefore, we easy decide what we should use on cases like this.

No comments:

Post a Comment