JDK-8210280 - Unnecessary reallocation when invoking HashMap.putAll()

Michal Vala mvala at redhat.com
Tue Dec 11 19:05:33 UTC 2018


I've been looking into this bug in HashMap where resize() is called multiple 
times when putting whole map into another.

I come up with following patch: 

I've tried to do it as little invasive as possible. New resize(int) method is 
called just from putMapEntries for now. Notice that method is called with size 
of the new map. I was experimenting with calling it with 'size()+s', but this 
leads to unwanted space allocation when inserted map rewrites a lot of existing 

I've benchmarked this with adding 10millions elements into existing map and it 
gets ~50% improvement:

Benchmark                Mode  Cnt  Score   Error  Units
MyBenchmark.testMethod  thrpt   10  1.248 ± 0.058  ops/s

Benchmark                Mode  Cnt  Score   Error  Units
MyBenchmark.testMethod  thrpt   10  1.872 ± 0.109  ops/s

public class MyBenchmark {
     static Map<Integer, Integer> mapTocopy = IntStream.range(1, 
10_000_000).boxed().collect(Collectors.toMap(k -> k,
             k -> k));

     public int testMethod() {
         var map = new HashMap<Integer, Integer>();
         map.put(-5, -5);
         return map.size();

Any ideas for missed corner-cases or some good tests?

Michal Vala
Red Hat Czech

More information about the core-libs-dev mailing list