Saturday, April 23, 2011

Few ways to improve the performance of your Java code

In the following post, I have shown several ways to improve the performance in your Java code. 


Appending string values in a loop


BAD
  String s = "";
  for (int i = 0; i < field.length; i++) {
    s = s + field[i];
  }

GOOD 
  StringBuffer buf = new StringBuffer();
  for (int i = 0; i < field.length; i++) {
    buf.append(field[i]);
  }
  String s = buf.toString();

When concatenating string in a loop, In each iteration, the String is converted to a StringBuffer/StringBuilder, appended to, and converted back to a String. these addtional cost can be avoided by directly using the second approach. 



Creating instance of  Integer,Long, Short, Character, and Byte

Using new Integer(int) is guaranteed to always result in a new object whereas Integer.valueOf(int) allows caching of values to be done by the compiler, class library, or JVM. Using of cached values avoids object allocation and the code will be faster.

Therefore Integer.valueOf(int) is better than using new Integer(int);
This is same for others (Long,Short,Character and Byte)



Accessing values in a Map.

BAD
for (Object key: map.keySet()){
    doSomething(map.get(key));
}
GOOD
for (Map.Entry entry: map.entrySet()){
    doSomething(entry.getValue());
}
It is more efficient to use an iterator on the entrySet of the map than using the keySet, to avoid the Map.get(key) lookup.

6 comments:

Scott said...

StringBuilder is a little better even than StringBuffer when the buffer is not shared across Threads.

Also, these are what I would call "micro-optimizations" and while certainly good practices, are rarely the source of application performance issues.

Always use a profiler to determine the cause of the issues before simply applying such micro-optimizations in the hopes that the performance will improve.

Finally, always measure performance before and after any code mods; you may defeat the JVM automatic optimizations in your efforts. Best to know the exact root cause and the exact impact of your changes.

mounir said...

VERY GOOD :P

StringBuffer buf = new StringBuffer();

int length = field.length; //+

for (int i = 0; i < length; i++) {
buf.append(field[i]);
}
String s = buf.toString();

Marian said...

Converting appending of strings to a StringBuilder version is done automatically by all standard javacs.
Using StringBuffer, as you suggest, actually makes it way slower :D
And next time you write about performance of some code examples, do some tests too, okay? ;)
Also, have you heard of so called premature optimization? These things you write about do not really matter much.

Mauricio Porras P said...

@Marian, you are so right. Like I say "Optimized code, the mark of the noob" LOL

Javin Paul said...

absolutely if you don't require synchronization go with StringBuilder that's the fastest available solution for this particular scenario.

Javin
How Synchronization works in Java

Kasun Weranga said...

@Marian, @Mauricio

+ operator is better than StringBuffer.append() only under certain condition. But in this example I am correct.
In this case string concatenation done at runtime So StringBuffer append is much more faster than + operator.

Please go through this artcle http://www.precisejava.com/javaperf/j2se/StringAndStringBuffer.htm#Strings104
you may find in which case StringBuffer is faster than + operator and vice versa.

Thanks,
Kasun.