Pages

Monday, November 25, 2013

Java8 HashMap is not compatible with Java7... in a way...

One of the things that shine in Java (not the only one!) is its performance. And it constantly improving. One of the performance improving features of Java8 is an improvement to HashMap and many related standard hashing collections. Actually from the title of this JEP (JDK Enhancement Proposal) "Handle Frequent HashMap Collisions with Balanced Trees" it is clear that this enhancement uses Comparable and Comparator functionality. If class do not implement Comparable interface or not Comparable with each other classes are stored in the map - Comparator based on the hashcode is used. But if class implements Comparable - this implementation is used.

So based on all this here is the very simple question. What does this code output on the JVM version 7 and on the JVM version 8?

Thursday, November 21, 2013

Benchmarking Guava's ImmutableMap

So I decided to bench (with the help of the excellent JMH suite) Guava's ImmutableMap. The first my try revealed some not expected results.

Source of the benchmark: Results: What I was not expected is that Guava's ImmutableMap with single entry is much faster to create than standard Collections.singletonMap(). Another surprise was in no performance benefits from using ImmutableMap with more than one entry comparing to HashMap and HashMap inside standard Collections.unmodifiableMap().

But this was test for creation of the map only. So here is the second version with simple work of the "contains" method: Results: The result is almost the same.

What is different in Collection.singletonMap comparing to the Guava's ImmutableMap is cached keySet, entrySet and values fields. I decided to make a little test to know whether not-initialized (and thus pointing to null) and not-used fields impact performance. Results: As it is seen the difference is significant. So probably the difference in Collections.singletonMap() and Guava's ImmutableMap is caused by these three fields even if they are not used.

In order to compare performance using these caching fields (or at least one of them) I made the third version: Results: Guava's ImmutableMap is still a bit better than Collections.singletonMap() but the difference is much less than in the first version. I assume that if using all the fields cached in standard version - it will be better.

Another surprise it no performance benefits from using Guava's Maps.newHashMapWithExpectedSize(). 128 entries is definitely enough to produce at least one rehash of the HashMap but probably they do not damage performance in a significant way, or there was really no rehashes since the expected size of the HashMap was inferred form the subsequent code but the JVM.

And the last surprise was that HashMap inside the Collections.unmodifiableMap() may have a better performance not only comparing to the Guava's ImmutableMap, but also comparing with exactly the same HashMap without any covers.