diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 8986bb5486c..0eb6d58c03c 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -848,7 +848,7 @@ public class ConcurrentHashMap extends AbstractMap * @param m the map */ public ConcurrentHashMap(Map m) { - this.sizeCtl = DEFAULT_CAPACITY; + this(m.size()); putAll(m); } @@ -1084,7 +1084,9 @@ public class ConcurrentHashMap extends AbstractMap * @param m mappings to be stored in this map */ public void putAll(Map m) { - tryPresize(m.size()); + if (table != null) { + tryPresize(size() + m.size()); + } for (Map.Entry e : m.entrySet()) putVal(e.getKey(), e.getValue(), false); } diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java b/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java index 283606f53ef..bd68e582e6a 100644 --- a/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java +++ b/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java @@ -28,6 +28,7 @@ import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; @@ -48,6 +49,7 @@ import java.util.concurrent.atomic.AtomicLong; public class Maps { private SimpleRandom rng; private Map map; + private Map staticMap; private Integer[] key; private int removesPerMaxRandom; @@ -55,9 +57,11 @@ public class Maps { private int total; private int position; + @Param("10000") + private int nkeys; + @Setup public void initTest() { - int nkeys = 10000; int pRemove = 10; int pInsert = 90; removesPerMaxRandom = (int) ((pRemove / 100.0 * 0x7FFFFFFFL)); @@ -65,10 +69,12 @@ public class Maps { rng = new SimpleRandom(); map = new ConcurrentHashMap<>(); + staticMap = new ConcurrentHashMap<>(); total = 0; key = new Integer[nkeys]; for (int i = 0; i < key.length; ++i) { key[i] = rng.next(); + staticMap.put(rng.next(), rng.next()); } position = key.length / 2; } @@ -106,6 +112,21 @@ public class Maps { position = pos; } + @Benchmark + public ConcurrentHashMap testConcurrentHashMapCopyConstructor() { + return new ConcurrentHashMap<>(staticMap); + } + + @Benchmark + public ConcurrentHashMap testConcurrentHashMapPutAll() { + ConcurrentHashMap map = new ConcurrentHashMap<>(nkeys); + for (int i = 0; i < nkeys; ++i) { + map.put(rng.next(), rng.next()); + } + map.putAll(staticMap); + return map; + } + private static class SimpleRandom { private final static long multiplier = 0x5DEECE66DL; private final static long addend = 0xBL;