The simple program below runs many times slower on 1.4 than it did on 1.3.1
The problem is in Hashmap.get(Object).
Eg on 296Mhz sparc system the loop in the program produces these timings:
JDK 1.3.1 : 860ms
JDK 1.4.0 : 4300ms
This is 5 times slower.
The reason is a new hashing mechanism works very poorly for the hash
codes returned from Doubles and every entry ends up in the 0th bucket so
search is almost linear. Double is a somewhat unusual key but we have one
customer app which uses it extensively and it is a performance critical
part of the application. Its unclear how common such problems would be
in hash codes from more common keys.
Its possible the app can be recoded to not use Double's but some way to get
the performance back in Hashmap.get() would be preferred.
The currently identified workaround is to create such a large capacity table
that the bitwise and to get the index of the bucket can come up with
different indexes.
For this app a capacity of at approx 2^17 is needed to restore to performance.
import java.util.*;
public class HM {
static int LEN=500;
public static void main(String args[]) {
HashMap hmap = new HashMap();
Double []dbls = new Double[LEN];
for (int i=0;i<LEN;i++) {
dbls[i] = new Double(i);
hmap.put(dbls[i], new Integer(i));
}
long t0 = System.currentTimeMillis();
for (int lc = 0; lc<1000; lc++) {
for (int i=0;i<LEN;i++) {
Object o = hmap.get(dbls[i]);
}
}
long t1 = System.currentTimeMillis();
System.out.println("time = "+(t1-t0));
}
}