Friday, 11 February 2011

String and the StringBuilder Usage

One common mistake you often see is code that relies on the repeated concatenation of strings using the String class. String concatenation using the String class okay when all you need to do is concatenate one string to another, but when it comes down to concatenating multiple strings, this method generates serious time penalties.

Consider the code below: both the stringBuilderMethod() and the stringMethod() create the same dummy error message, but the stringBuilderMethod() does it far more efficiently. This is because in stringMethod() the following scenario occurs:
  1. A string str is created pointing to the String pool value.
  2. If the message is not null a new string is created by combining message and the initial string assigning it to the original string reference.
  3. The same happens again when " at " is appended to str.
  4. If location is not null then a further string is created by appending the message to our string by creating a further new string and again assigning it to str.
  5. Finally, another new string is create by appending " Press any key to exit" to str and re-assigning str to this object.
  6. Now we have a complete str object, but I’ll guess that the garbage collector will now be working over time to clean up all the intermediate string objects created as a by product of this code.
The StringBuilder method does the same thing but far more efficiently as you can see from the sample output:

Using Strings took 71037nS
Using StringBuilder took 9034nS

Although the API states that System.nanoTime() “provides nanosecond precision, but not necessarily nanosecond accuracy”, you can see that using StringBuilder is about 7.8 times quicker than using String.

String Test Code


public class StringPerformance2 {

 
public static void main(String[] args) {

   
long start = System.nanoTime();
    badMethod
("Test Message", "Watery Lane");
   
long duration = System.nanoTime() - start;
    System.out.println
("Using Strings took " + duration + "nS");

    start = System.nanoTime
();
    goodMethod
("Test Message", "Watery Lane");
    duration = System.nanoTime
() - start;
    System.out.println
("Using StringBuilder took " + duration + "nS");
 
}

 
/*
   * Bad Code! This is not the way to do this...
   */
 
private static String badMethod(String message, String location) {

   
String str = "Exception closing down ";

   
if (message != null)
     
str += message;

   
if (location != null) {
     
str += " at ";
      str += location;

      str +=
" Press any key to exit";
   
}

   
return str;
 
}

 
private static String goodMethod(String message, String location) {

   
// Create a message the proper way..
   
StringBuilder str = new StringBuilder("Exception closing down ");

   
if (message != null)
     
str.append(message);

   
if (location != null) {
     
str.append(" at ");
      str.append
(location);
   
}

   
str.append(" Press any key to exit");

   
return str.toString();
 
}
}

No comments: