Month: June 2014

How Java uses StringBuilder class for Byte code optimizations ?


We all know Strings in java are immutable. This means that whenever we modify a String, it creates a new String object with the modified value and throws the old one away (of course, If there are no other references to it). Hence concatenations using Strings are expensive, consuming both time and memory.The obvious solution is to use the StringBuilder Class which is not immutable.

No StringBuilder, it’s still fine !!

But does this mean that we need to explicitly use StringBuilder objects in java code ? Consider the following example.

int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6;
String s = "String Concatenation Example" + a + b + c + d + e + f;

Considering the immutability aspect of String, how do we expect the java runtime to execute the above example ? First it would have to create a String object with value "String Concatenation Example". Then it would create another string with the value of variable 'a' appended to the first one and then throw away the string object created initially (ie makes it eligible for garbage collection). This process of creation and throwing away would be repeated until all the variables mentioned in the statement are appended.

Well, if you thought that that is how it works. Then you are wrong. Starting from Java 1.6.x, the java compiler does some byte code optimization to handle this in a different way. To find out, i used a decompiler to decompile the bytecode (.class file), and this is what i found.

int a = 1; int b = 2; int c = 3; int d = 4; int e = 5; int f = 6; 
String s = (new StringBuilder("StringConcatenationExample")).append(a).append(b).append(c).append(d).append(e).append(f).toString();

The Java compiler, finding that developer uses String.concat() or + to concatenate multiple strings, optimizes the code during compile time and replaces it with a StringBuilder object.

What this means is that the java compiler lets us use the conventional way of string concatenations ( thus retaining the readability of the code ), but works in the background during compilation to implement these concatenations using the StringBuilder object thus saving on both memory and time for these computations.

Where i really need the StringBuilder !!

Now,can we assume that we can use conventional string concatenations ( using string.concat or + ) in all constructs and expect the compiler to do the optimization for us. Well, Think again !!

Consider the following example.

String s = "";
for (int i = 0; i < 100; i++) {
   s += i;
}

On decompilation, this gives

for(int i = 0; i < 100; i++) 
   s = (new StringBuilder(string.valueOf(s))).append(i).toString();

Here the compiler does convert the concatenation operation to a StringBuilder. However, it creates a new StringBuilder object for every iteration of the loop which obviously is a waste of memory. The better way to code this would be :

StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 100; i++) {

	stringBuilder.append(i);
}
System.out.println(stringBuilder.toString());

Some Thumb Rules !!

Hence the thumb rules to be applied here are, for regular constructs, use conventional String concatenation, for it’s readability and when performing String concatenations within loops, use the StringBuilder class.

Advertisements

The Maven Integration requires that Eclipse be running in a jdk [solved]


MavenEclipseException

What do you do when you get this Exception in Eclipse ?

Answer : You need to add/edit the eclipse.ini file in your $ECLIPSE_HOME ( if you have one ) or the default one in your Eclipse installation directory with following details.

-vm
/home/user/java/jdk1.6.0_33/bin/java

Add the -vm option before the -vmargs option. Of course the exact location of your java will be different! For more on eclipse.ini, go to the eclipse wiki here.