Hi,

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: http://cr.openjdk.java.net/~mvala/jdk/jdk/JDK-8210280/webrev.00/

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 keys.

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

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

patched
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));

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

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

--
Michal Vala
OpenJDK QE
Red Hat Czech

Reply via email to