From 5a0fe36e18fc07f3216bef4fb21329bd2bc39f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Wed, 21 Oct 2020 11:30:12 +0200 Subject: [PATCH] add jmh benchmarking --- datastructures-tiny/build.gradle | 19 +++- .../tiny/jmh/CollectionAdditionTest.java | 84 ++++++++++++++ .../tiny/jmh/CollectionRemovalTest.java | 97 ++++++++++++++++ .../tiny/jmh/CollectionRetrievalTest.java | 100 +++++++++++++++++ .../tiny/jmh/MapAdditionTest.java | 83 ++++++++++++++ .../tiny/jmh/MapRemovalTest.java | 105 +++++++++++++++++ .../tiny/jmh/MapRetrievalTest.java | 106 ++++++++++++++++++ gradle/compile/java.gradle | 6 +- 8 files changed, 596 insertions(+), 4 deletions(-) create mode 100644 datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionAdditionTest.java create mode 100644 datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionRemovalTest.java create mode 100644 datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionRetrievalTest.java create mode 100644 datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapAdditionTest.java create mode 100644 datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapRemovalTest.java create mode 100644 datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapRetrievalTest.java diff --git a/datastructures-tiny/build.gradle b/datastructures-tiny/build.gradle index deb931e..458148a 100644 --- a/datastructures-tiny/build.gradle +++ b/datastructures-tiny/build.gradle @@ -1,3 +1,20 @@ +sourceSets { + jmh { + java.srcDirs = ['src/jmh/java'] + resources.srcDirs = ['src/jmh/resources'] + compileClasspath += sourceSets.main.runtimeClasspath + } +} + dependencies { api project(':datastructures-common') -} \ No newline at end of file + jmhImplementation 'org.openjdk.jmh:jmh-core:1.21' + jmhAnnotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:1.21' +} + +task jmh(type: JavaExec, group: 'jmh', dependsOn: jmhClasses) { + main = 'org.openjdk.jmh.Main' + classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath +} + +classes.finalizedBy(jmhClasses) diff --git a/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionAdditionTest.java b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionAdditionTest.java new file mode 100644 index 0000000..ca97090 --- /dev/null +++ b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionAdditionTest.java @@ -0,0 +1,84 @@ +package org.xbib.datastructures.tiny.jmh; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.xbib.datastructures.tiny.TinySet; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 10) +@Fork(1) +@Measurement(iterations = 10) +public class CollectionAdditionTest { + + private static final int COLLECTION_SIZE = 1_000_000; + + @Benchmark + public List arrayList() { + List list = new ArrayList<>(); + for (int i = 0; i < COLLECTION_SIZE; i++) { + list.add(i); + } + return list; + } + + @Benchmark + public List linkedList() { + List list = new LinkedList<>(); + for (int i = 0; i < COLLECTION_SIZE; i++) { + list.add(i); + } + return list; + } + + @Benchmark + public Set hashSet() { + Set set = new HashSet<>(); + for (int i = 0; i < COLLECTION_SIZE; i++) { + set.add(i); + } + return set; + } + + @Benchmark + public Set linkedHashSet() { + Set set = new LinkedHashSet<>(); + for (int i = 0; i < COLLECTION_SIZE; i++) { + set.add(i); + } + return set; + } + + @Benchmark + public Set treeSet() { + Set set = new TreeSet<>(); + for (int i = 0; i < COLLECTION_SIZE; i++) { + set.add(i); + } + return set; + } + + + @Benchmark + public Set tinySet() { + TinySet.Builder setBuilder = TinySet.builder(); + for (int i = 0; i < COLLECTION_SIZE; i++) { + setBuilder.add(i); + } + return setBuilder.build(); + } +} diff --git a/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionRemovalTest.java b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionRemovalTest.java new file mode 100644 index 0000000..015852b --- /dev/null +++ b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionRemovalTest.java @@ -0,0 +1,97 @@ +package org.xbib.datastructures.tiny.jmh; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.xbib.datastructures.tiny.TinySet; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.TreeSet; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 10) +@Fork(1) +@Measurement(iterations = 10) +public class CollectionRemovalTest { + + private static final int COLLECTION_SIZE = 25_000; + + private ArrayList arrayList; + private LinkedList linkedList; + private HashSet hashSet; + private LinkedHashSet linkedHashSet; + private TreeSet treeSet; + private TinySet.Builder tinySet; + + @Setup(Level.Trial) + public void setup() { + arrayList = new ArrayList<>(); + linkedList = new LinkedList<>(); + hashSet = new HashSet<>(); + linkedHashSet = new LinkedHashSet<>(); + treeSet = new TreeSet<>(); + tinySet = TinySet.builder(); + for (int i = 0; i < COLLECTION_SIZE; i++) { + arrayList.add(i); + linkedList.add(i); + hashSet.add(i); + linkedHashSet.add(i); + treeSet.add(i); + tinySet.add(i); + } + } + + @Benchmark + public void arrayList(Blackhole bh) { + for (int i = 0; i < COLLECTION_SIZE; i++) { + Integer remove = arrayList.remove(i); + } + } + + @Benchmark + public void linkedList(Blackhole bh) { + for (int i = 0; i < COLLECTION_SIZE; i++) { + Integer remove = linkedList.remove(i); + } + } + + @Benchmark + public void hashSet(Blackhole bh) { + for (int i = 0; i < COLLECTION_SIZE; i++) { + boolean remove = hashSet.remove(i); + } + } + + @Benchmark + public void linkedHashSet(Blackhole bh) { + for (int i = 0; i < COLLECTION_SIZE; i++) { + boolean remove = linkedHashSet.remove(i); + } + } + + @Benchmark + public void treeSet(Blackhole bh) { + for (int i = 0; i < COLLECTION_SIZE; i++) { + boolean remove = treeSet.remove(i); + } + } + + @Benchmark + public void tinySet(Blackhole bh) { + for (int i = 0; i < COLLECTION_SIZE; i++) { + boolean remove = tinySet.remove(i); + } + } +} diff --git a/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionRetrievalTest.java b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionRetrievalTest.java new file mode 100644 index 0000000..b797f81 --- /dev/null +++ b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/CollectionRetrievalTest.java @@ -0,0 +1,100 @@ +package org.xbib.datastructures.tiny.jmh; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.xbib.datastructures.tiny.TinySet; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.TreeSet; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 10) +@Fork(1) +@Measurement(iterations = 10) +public class CollectionRetrievalTest { + + private static final int COLLECTION_SIZE = 25_000; + + private ArrayList arrayList; + private LinkedList linkedList; + private HashSet hashSet; + private LinkedHashSet linkedHashSet; + private TreeSet treeSet; + private TinySet tinySet; + + @Setup(Level.Trial) + public void setup() { + arrayList = new ArrayList<>(); + linkedList = new LinkedList<>(); + hashSet = new HashSet<>(); + linkedHashSet = new LinkedHashSet<>(); + treeSet = new TreeSet<>(); + TinySet.Builder tinySetBuilder = TinySet.builder(); + for (int i = 0; i < COLLECTION_SIZE; i++) { + arrayList.add(i); + linkedList.add(i); + hashSet.add(i); + linkedHashSet.add(i); + treeSet.add(i); + tinySetBuilder.add(i); + } + tinySet = tinySetBuilder.build(); + } + + @Benchmark + public void arrayList(Blackhole bh) { + for (int i = 0; i < COLLECTION_SIZE; i++) { + Integer elem = arrayList.get(i); + bh.consume(elem); + } + } + + @Benchmark + public void linkedList(Blackhole bh) { + for (int i = 0; i < COLLECTION_SIZE; i++) { + Integer elem = linkedList.get(i); + bh.consume(elem); + } + } + + @Benchmark + public void hashSetIterator(Blackhole bh) { + for (Integer elem : hashSet) { + bh.consume(elem); + } + } + + @Benchmark + public void linkedHashSetIterator(Blackhole bh) { + for (Integer elem : linkedHashSet) { + bh.consume(elem); + } + } + + @Benchmark + public void treeSetIterator(Blackhole bh) { + for (Integer elem : treeSet) { + bh.consume(elem); + } + } + + @Benchmark + public void tinySetIterator(Blackhole bh) { + for (Integer elem : tinySet) { + bh.consume(elem); + } + } +} diff --git a/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapAdditionTest.java b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapAdditionTest.java new file mode 100644 index 0000000..c6576ca --- /dev/null +++ b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapAdditionTest.java @@ -0,0 +1,83 @@ +package org.xbib.datastructures.tiny.jmh; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.xbib.datastructures.tiny.TinyMap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 10) +@Fork(value = 1) +@Measurement(iterations = 10) +public class MapAdditionTest { + + private static final int COLLECTION_SIZE = 1_000_000; + + @Benchmark + public Map hashMap() { + Map map = new HashMap<>(); + for (long i = 0; i < COLLECTION_SIZE; i++) { + map.put(i, String.valueOf(i)); + } + return map; + } + + @Benchmark + public Map linkedHashMap() { + Map map = new LinkedHashMap<>(); + for (long i = 0; i < COLLECTION_SIZE; i++) { + map.put(i, String.valueOf(i)); + } + return map; + } + + @Benchmark + public Map treeMap() { + Map map = new TreeMap<>(); + for (long i = 0; i < COLLECTION_SIZE; i++) { + map.put(i, String.valueOf(i)); + } + return map; + } + + @Benchmark + public Map synchronizedHashMap() { + Map map = new HashMap<>(); + map = Collections.synchronizedMap(map); + for (long i = 0; i < COLLECTION_SIZE; i++) { + map.put(i, String.valueOf(i)); + } + return map; + } + + @Benchmark + public Map concurrentHashMap() { + ConcurrentHashMap map = new ConcurrentHashMap<>(); + for (long i = 0; i < COLLECTION_SIZE; i++) { + map.put(i, String.valueOf(i)); + } + return map; + } + + @Benchmark + public Map tinyMap() { + TinyMap.Builder map = TinyMap.builder(); + for (long i = 0; i < COLLECTION_SIZE; i++) { + map.put(i, String.valueOf(i)); + } + return map.build(); + } +} diff --git a/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapRemovalTest.java b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapRemovalTest.java new file mode 100644 index 0000000..7ea61c6 --- /dev/null +++ b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapRemovalTest.java @@ -0,0 +1,105 @@ +package org.xbib.datastructures.tiny.jmh; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.xbib.datastructures.tiny.TinyMap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 10) +@Fork(value = 1) +@Measurement(iterations = 10) +public class MapRemovalTest { + + private static final int COLLECTION_SIZE = 25_000; + + private HashMap hashMap; + private LinkedHashMap linkedHashMap; + private TreeMap treeMap; + private ConcurrentHashMap concurrentHashMap; + private Map synchronizedHashMap; + private TinyMap.Builder tinyMap; + + @Setup(Level.Trial) + public void setup() { + hashMap = new HashMap<>(); + linkedHashMap = new LinkedHashMap<>(); + treeMap = new TreeMap<>(); + concurrentHashMap = new ConcurrentHashMap<>(); + synchronizedHashMap = new HashMap<>(); + tinyMap = TinyMap.builder(); + for (long i = 0; i < COLLECTION_SIZE; i++) { + hashMap.put(i, String.valueOf(i)); + linkedHashMap.put(i, String.valueOf(i)); + treeMap.put(i, String.valueOf(i)); + concurrentHashMap.put(i, String.valueOf(i)); + synchronizedHashMap.put(i, String.valueOf(i)); + tinyMap.put(i, String.valueOf(i)); + } + synchronizedHashMap = Collections.synchronizedMap(synchronizedHashMap); + } + + @Benchmark + public void hashMap(Blackhole bh) { + for (long i = 0L; i < COLLECTION_SIZE; i++) { + String s = hashMap.remove(i); + bh.consume(s); + } + } + + @Benchmark + public void linkedHashMap(Blackhole bh) { + for (long i = 0L; i < COLLECTION_SIZE; i++) { + String s = linkedHashMap.remove(i); + bh.consume(s); + } + } + + @Benchmark + public void treeMap(Blackhole bh) { + for (long i = 0L; i < COLLECTION_SIZE; i++) { + String s = treeMap.remove(i); + bh.consume(s); + } + } + + @Benchmark + public void synchronizedHashMap(Blackhole bh) { + for (long i = 0L; i < COLLECTION_SIZE; i++) { + String s = synchronizedHashMap.remove(i); + bh.consume(s); + } + } + + @Benchmark + public void concurrentHashMap(Blackhole bh) { + for (long i = 0L; i < COLLECTION_SIZE; i++) { + String s = concurrentHashMap.remove(i); + bh.consume(s); + } + } + + @Benchmark + public void tinyMap(Blackhole bh) { + for (long i = 0L; i < COLLECTION_SIZE; i++) { + String s = tinyMap.remove(i); + bh.consume(s); + } + } +} diff --git a/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapRetrievalTest.java b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapRetrievalTest.java new file mode 100644 index 0000000..2146df4 --- /dev/null +++ b/datastructures-tiny/src/jmh/java/org/xbib/datastructures/tiny/jmh/MapRetrievalTest.java @@ -0,0 +1,106 @@ +package org.xbib.datastructures.tiny.jmh; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.xbib.datastructures.tiny.TinyMap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; + +@State(Scope.Benchmark) +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 10) +@Fork(1) +@Measurement(iterations = 10) +public class MapRetrievalTest { + + private static final int COLLECTION_SIZE = 25_000; + + private HashMap hashMap; + private LinkedHashMap linkedHashMap; + private TreeMap treeMap; + private ConcurrentHashMap concurrentHashMap; + private Map synchronizedHashMap; + private TinyMap tinyMap; + + @Setup(Level.Trial) + public void setup() { + hashMap = new HashMap<>(); + linkedHashMap = new LinkedHashMap<>(); + treeMap = new TreeMap<>(); + concurrentHashMap = new ConcurrentHashMap<>(); + synchronizedHashMap = new HashMap<>(); + TinyMap.Builder tinyMapBuilder = TinyMap.builder(); + for (long i = 0; i < COLLECTION_SIZE; i++) { + hashMap.put(i, String.valueOf(i)); + linkedHashMap.put(i, String.valueOf(i)); + treeMap.put(i, String.valueOf(i)); + concurrentHashMap.put(i, String.valueOf(i)); + synchronizedHashMap.put(i, String.valueOf(i)); + tinyMapBuilder.put(i, String.valueOf(i)); + } + synchronizedHashMap = Collections.synchronizedMap(synchronizedHashMap); + tinyMap = tinyMapBuilder.build(); + } + + @Benchmark + public void hashMap(Blackhole bh) { + for (long i = 0; i < COLLECTION_SIZE; i++) { + String s = hashMap.get(i); + bh.consume(s); + } + } + + @Benchmark + public void linkedHashMap(Blackhole bh) { + for (long i = 0; i < COLLECTION_SIZE; i++) { + String s = linkedHashMap.get(i); + bh.consume(s); + } + } + + @Benchmark + public void treeMap(Blackhole bh) { + for (long i = 0; i < COLLECTION_SIZE; i++) { + String s = treeMap.get(i); + bh.consume(s); + } + } + + @Benchmark + public void synchronizedHashMap(Blackhole bh) { + for (long i = 0; i < COLLECTION_SIZE; i++) { + String s = synchronizedHashMap.get(i); + bh.consume(s); + } + } + + @Benchmark + public void concurrentHashMap(Blackhole bh) { + for (long i = 0; i < COLLECTION_SIZE; i++) { + String s = concurrentHashMap.get(i); + bh.consume(s); + } + } + + @Benchmark + public void tinyhMap(Blackhole bh) { + for (long i = 0; i < COLLECTION_SIZE; i++) { + String s = tinyMap.get(i); + bh.consume(s); + } + } +} diff --git a/gradle/compile/java.gradle b/gradle/compile/java.gradle index db72f9f..1624344 100644 --- a/gradle/compile/java.gradle +++ b/gradle/compile/java.gradle @@ -36,9 +36,9 @@ artifacts { archives sourcesJar, javadocJar } -tasks.withType(JavaCompile) { - options.compilerArgs << '-Xlint:all,-exports' -} +//tasks.withType(JavaCompile) { +// options.compilerArgs << '-Xlint:all' +//} javadoc { options.addStringOption('Xdoclint:none', '-quiet')