I stumbled upon a bizarre performance issue related to the StringBuilder's append method. I noticed what appeared to be a foolish mistake - string concatenation during the use of the StringBuilder constructor (this even shows up as a warning in the NetBeans IDE).
Version 1
int hash = -1; //lazily computed, also present in Version 2 int blockID = ... //0 to 1000, also present in Version 2 int threadID = ... //0 to 1000, also present in Version 2 boolean hashed = false; //also present in Version 2 @Override public int hashCode(){ if(!hashed){ StringBuilder s = new StringBuilder(blockID+":"+threadID); hash = s.toString().hashCode(); hashed= true; } return hash; } Millions of these objects are created during runtime, so I thought by making the following change, it would provide some speedup:
Version 2
@Override public int hashCode(){ if(!hashed){ StringBuilder s = new StringBuilder(blockID); s.append(":"); s.append(threadID); hash = s.toString().hashCode(); hashed = true; } return hash; } WRONG! Turns out, Version 2 is literally 100X slower than Version 1. Why???
Additional Info
I am compiling against Java 6 (customer requirement), and I am using Oracle's JVM.
My performance test involves creating a million of these objects and throwing them into a HashMap. It takes half a second to do it using Version 1, but almost 50 seconds to do it using Version 2.
hash = (blockID+":"+threadID).hashCode();blockID + ":" + threadID? And why building a String to compute the hashCode of 2 integers? Let the IDE generate the code for you: it will be much more efficient.+to be faster than usingStringBuilder- even in a loop where using aStringBuilderis supposed to be faster.