HashMap collision speed (regression 7->8)

Peter Levart peter.levart at gmail.com
Thu Jan 8 19:22:13 UTC 2015


Hi Bernd,

It seems that only bad hash codes (without comparable keys) in JDK8 HM 
are worse than JDK7 HM.


Since you have already taken time to measure JDK7 vs JDK8 HM, could you 
try to take the JDK8 source and just replace the internal 
"comparableClassFor" method with the following implementation:

     static final ClassValue<Boolean> selfComparable = new 
ClassValue<Boolean>() {
         @Override
         protected Boolean computeValue(Class<?> c) {
             Type[] as; ParameterizedType p;
             for (Type t : c.getGenericInterfaces()) {
                 if (t instanceof ParameterizedType &&
                     (p = (ParameterizedType) t).getRawType() == 
Comparable.class &&
                     (as = p.getActualTypeArguments()).length == 1 &&
                     as[0] == c) // type arg is c
                     return true;
             }
             return false;
         }
     };

     static Class<?> comparableClassFor(Object x) {
         if (x instanceof Comparable) {
             Class<?> c = x.getClass();
             if (c == String.class || selfComparable.get(c)) {
                 return c;
             }
         }
         return null;
     }


...and retry your measurements. I just want to see if it has any impact.


Thanks, Peter


On 01/08/2015 05:38 PM, Bernd Eckenfels wrote:
> Hello,
>
> I think it was topic before, but I just wanted to point out, that it is
> still an topic on the internetz. :)
>
> Motivated by a StackOverflow question regarding HashMap performance
> regression in Java 8
>
> http://stackoverflow.com/questions/27759527/using-java-7-hashmap-in-java-8/27760442
>
> I made a JMH test and compared 7 and 8 speed. (the test is not very scientific as I dont really know how to squeeze the longrunning loop which alters state into the harness, but the results seem to be consitent wth theory and stopwatch testing)
>
> https://gist.github.com/ecki/9f69773eb29428a36077
>
> What can be seen is, that with a good distribution of hash keys 8 looks
> faster than 7, and with a bad distribution of hash keys Java 7 is
> faster (unless you supply a Comparator for the key). (and a good distributed hashkey with comparable seems to be a bit slower)
>
> I think the regression is somewhat expected, but I guess its not widely
> known.
>
> (I do not use a cached hashcode, but it has a nearly trivial implementation just to make it more life like. the tests also compares different initial sizes, but they do not have
> an measurable effect on the performance, I show only default size below:)
>
> java version "1.7.0_72"
>   
> Benchmark                      (initialSize) Mode Samp Score    Error Units
> n.e.j.h.HashMapCollision.badDistNoComp 16    avgt 4   10847,318 ± 5596,690 ms/op
> n.e.j.h.HashMapCollision.badDistWithComp 16  avgt 4   10761,430 ± 5376,975 ms/op
> n.e.j.h.HashMapCollision.goodDistNoComp 16   avgt 4    3613,923 ± 254,823 ms/op
> n.e.j.h.HashMapCollision.goodDistWithComp 16 avgt 4    3656,229 ± 274,350 ms/op
>   
>   
> java version "1.8.0_25"
>   
> Benchmark                      (initialSize) Mode Samp Score     Error Units
> n.e.j.h.HashMapCollision.badDistNoComp 16    avgt 4    14309,880 ± 1811,709 ms/op <-slower
> n.e.j.h.HashMapCollision.badDistWithComp 16  avgt 4     8232,037 ± 5974,530 ms/op
> n.e.j.h.HashMapCollision.goodDistNoComp 16   avgt 4     3304,698 ± 116,866 ms/op
> n.e.j.h.HashMapCollision.goodDistWithComp 16 avgt 4     3425,762 ± 107,659 ms/op
>
>
> Greetings
> Bernd




More information about the core-libs-dev mailing list