Skip to content

Commit

Permalink
[Backport] 8322149: ConcurrentHashMap smarter presizing for copy cons…
Browse files Browse the repository at this point in the history
…tructor and putAll

Summary: ConcurrentHashMap::ConcurrentHashMap() -> putAll() -> tryPresize() -> transfer() does a lot of unnecessary work. There is nothing to transfer from the old table, since the table is just being initialized.

Testing: CI testing

Reviewers: lingjun-cg, yuleil

Issue: dragonwell-project#101
  • Loading branch information
MaxXSoft committed Aug 30, 2024
1 parent ecd5d2e commit 9eb35d8
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ public ConcurrentHashMap(int initialCapacity) {
* @param m the map
*/
public ConcurrentHashMap(Map<? extends K, ? extends V> m) {
this.sizeCtl = DEFAULT_CAPACITY;
this(m.size());
putAll(m);
}

Expand Down Expand Up @@ -1084,7 +1084,9 @@ else if (f instanceof ReservationNode)
* @param m mappings to be stored in this map
*/
public void putAll(Map<? extends K, ? extends V> m) {
tryPresize(m.size());
if (table != null) {
tryPresize(size() + m.size());
}
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
putVal(e.getKey(), e.getValue(), false);
}
Expand Down
23 changes: 22 additions & 1 deletion test/micro/org/openjdk/bench/java/util/concurrent/Maps.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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;
Expand All @@ -48,27 +49,32 @@
public class Maps {
private SimpleRandom rng;
private Map<Integer, Integer> map;
private Map<Integer, Integer> staticMap;
private Integer[] key;

private int removesPerMaxRandom;
private int insertsPerMaxRandom;
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));
insertsPerMaxRandom = (int) ((pInsert / 100.0 * 0x7FFFFFFFL));

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;
}
Expand Down Expand Up @@ -106,6 +112,21 @@ public void testConcurrentHashMap() {
position = pos;
}

@Benchmark
public ConcurrentHashMap<Integer, Integer> testConcurrentHashMapCopyConstructor() {
return new ConcurrentHashMap<>(staticMap);
}

@Benchmark
public ConcurrentHashMap<Integer, Integer> testConcurrentHashMapPutAll() {
ConcurrentHashMap<Integer, Integer> 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;
Expand Down

0 comments on commit 9eb35d8

Please sign in to comment.