Skip to content

Instantly share code, notes, and snippets.

@wiikviz
Forked from duarten/HashMapBenchmark.java
Created December 4, 2016 21:07
Show Gist options
  • Select an option

  • Save wiikviz/730e3ad2a5acd7dbb8df12946261c33d to your computer and use it in GitHub Desktop.

Select an option

Save wiikviz/730e3ad2a5acd7dbb8df12946261c33d to your computer and use it in GitHub Desktop.
Concurrent maps benchmarks
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import scala.collection.concurrent.TrieMap;
import org.openjdk.jmh.annotations.*;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5, time = 2)
@Fork(5)
@Threads(Threads.MAX)
public class HashMapBenchmark {
static final int numValues = 10240; // Power of 2
static final int mask = numValues - 1;
@State(Scope.Benchmark)
public static class JavaMap {
public UUID[] uuids;
public HashMap<UUID, Object> map;
@Setup
public void setup() {
map = new HashMap<>();
uuids = new UUID[numValues];
for (int i = 0; i < numValues; ++i) {
uuids[i] = UUID.randomUUID();
Object value = new Object();
map.put(uuids[i], value);
}
}
}
@State(Scope.Benchmark)
public static class ConcurrentMap {
public UUID[] uuids = new UUID[numValues];
public ConcurrentHashMap<UUID, Object> map;
@Setup
public void setup() {
map = new ConcurrentHashMap<>();
uuids = new UUID[numValues];
for (int i = 0; i < numValues; ++i) {
uuids[i] = UUID.randomUUID();
Object value = new Object();
map.put(uuids[i], value);
}
}
}
@State(Scope.Benchmark)
public static class ScalaTrieMap {
public UUID[] uuids = new UUID[numValues];
public TrieMap<UUID, Object> map;
@Setup
public void setup() {
map = new TrieMap<>();
uuids = new UUID[numValues];
for (int i = 0; i < numValues; ++i) {
uuids[i] = UUID.randomUUID();
Object value = new Object();
map.put(uuids[i], value);
}
}
}
@State(Scope.Thread)
public static class Index {
public int value;
@Setup
public void setup() {
value = (int) (Thread.currentThread().getId() * System.nanoTime() * 31);
}
}
// Read throughput
@Benchmark
public Object measureReadJava(JavaMap state, Index index) {
return state.map.get(getUuid(state.uuids, index));
}
@Benchmark
public Object measureReadConcurrent(ConcurrentMap state, Index index) {
return state.map.get(getUuid(state.uuids, index));
}
@Benchmark
public Object measureReadTrie(ScalaTrieMap state, Index index) {
return state.map.get(getUuid(state.uuids, index)).get();
}
// Write throughput
@Benchmark
@Threads(1)
public Object measureWriteJava(JavaMap state, Index index) {
return state.map.put(getUuid(state.uuids, index), state);
}
@Benchmark
@Threads(1)
public Object measureWriteConcurrent(ConcurrentMap state, Index index) {
return state.map.put(getUuid(state.uuids, index), state);
}
@Benchmark
@Threads(1)
public Object measureWriteTrie(ScalaTrieMap state, Index index) {
return state.map.put(getUuid(state.uuids, index), state);
}
// Readers with concurrent writer
@Benchmark
@Group("readsAndWritesTrie")
public Object measureReadersWithWriters(ScalaTrieMap state, Index index) {
return state.map.get(getUuid(state.uuids, index)).get();
}
@Benchmark
@Group("readsAndWritesTrie")
@GroupThreads(1)
public Object measureWriter(ScalaTrieMap state, Index index) {
int idx = index.value++ & mask;
UUID key = (idx & 1) == 0 ? state.uuids[idx] : UUID.randomUUID();
return state.map.put(key, state);
}
@Benchmark
@Group("readsAndWritesConcurrent")
public Object measureReadersWithWritersConc(ConcurrentMap state, Index index) {
return state.map.get(getUuid(state.uuids, index));
}
@Benchmark
@Group("readsAndWritesConcurrent")
@GroupThreads(1)
public Object measureWriterConc(ConcurrentMap state, Index index) {
int idx = index.value++ & mask;
UUID key = (idx & 1) == 0 ? state.uuids[idx] : UUID.randomUUID();
return state.map.put(key, state);
}
// Readers with concurrent remove
@Benchmark
@Group("readsAndRemovesTrie")
public Object measureReadersWithRemovers(ScalaTrieMap state, Index index) {
return state.map.get(getUuid(state.uuids, index));
}
@Benchmark
@Group("readsAndRemovesTrie")
@GroupThreads(1)
public Object measureRemover(ScalaTrieMap state, Index index) {
return state.map.remove(getUuid(state.uuids, index));
}
@Benchmark
@Group("readsAndRemovesConcurrent")
public Object measureReadersWithRemoversConc(ConcurrentMap state, Index index) {
return state.map.get(getUuid(state.uuids, index));
}
@Benchmark
@Group("readsAndRemovesConcurrent")
@GroupThreads(1)
public Object measureRemoverConc(ConcurrentMap state, Index index) {
return state.map.remove(getUuid(state.uuids, index));
}
// Utility method
@CompilerControl(CompilerControl.Mode.INLINE)
public UUID getUuid(UUID[] uuids, Index index) {
return uuids[index.value++ & mask];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment