Wednesday, October 15, 2008

Use StringBuffer instead of += -- Will this really help??

A very commonly suggested optimization technique for Java is to use a StringBuffer instead of a String when concatenating. Typical reaosn would be that using the + or += operators to concatenate strings causes a new object to be created for each concatenation. On the other hand, the StringBuffer contains an append() method, which allows dynamic string growth without having to create a new String object each time.

But we have a catch here, this can sometimes be observed as ineffecient or not effective as much as it is expected to be. Why? - This can be explained as below.

Take the example

Snip1:: String s1 = "Hello";
s1 = s1 + " XX";

Snip2:: StringBuffer sb = new StringBuffer("Hello");

Now when both the above snips are compiled. In snip1, the compiler is smart enough to recognize when a number of concatenations are going to be executed and automatically creates a StringBuffer. Each concatenation operation is converted to append() calls behind the scenes.
So frankly, manually coding a StringBuffer is unnecessary, unless the following reason is considered.

In order for a StringBuffer to truly optimize concatenation, it must be seeded properly. In other words, it needs to be given an appropriate initial size. This is because the StringBuffer keeps the characters of the string it is maintaining in an array. When append() is called, the StringBuffer checks the size of the character array versus the estimated size of the new string. If the estimated size is larger than the actual array, a new array is created and the old array is copied to the new one. Thus, StringBuffer is not only creating a new object for each concatenation, but it also incurs the overhead of copying all the indexes of the original array.

This can be overhead when using the default constructor. In that case, size defaults to character array of size to a measly 16 characters. The most used scenario in any application coding is SQL String creation. SQL strings assuredly will exceed 16 characters and constantly cause new character array objects to be created. Even using the StringBuffer's constructor that takes in a String only initializes the character array as 16 characters more than the length of the String argument.

Hence, the best way to be sure that the StringBuffer will benefit the performance of your application is to give it a large enough initial seed that it will need to create its character array only once based on your requirement.

No comments:

Post a Comment