|
|
@@ -0,0 +1,323 @@
|
|
|
+/*
|
|
|
+ * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
+ * @copyright Ranides Atterwim
|
|
|
+ * @license WTFPL
|
|
|
+ * @url http://ranides.net/projects/
|
|
|
+ */
|
|
|
+package net.ranides.assira.collection.map;
|
|
|
+
|
|
|
+import com.google.caliper.Runner;
|
|
|
+import com.google.caliper.SimpleBenchmark;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.SortedMap;
|
|
|
+import java.util.TreeMap;
|
|
|
+import net.ranides.assira.math.Randomizer;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Comparison of performance #get methods
|
|
|
+ *
|
|
|
+ * RESULTS:
|
|
|
+ *
|
|
|
+ * Integer:
|
|
|
+ * SIZE DOMAIN 1/HIT NAME TREE SWITCH HASH RATIO
|
|
|
+ * 32 1K 30 TT 55 55 40 73%
|
|
|
+ * 256 1K 4 SS 79 82 41 50%
|
|
|
+ * 256 100K 400 SM 79 89 39 43%
|
|
|
+ * 256 1 000M 4M SL 81 84 39 46%
|
|
|
+ * 10 000 1 000M 100K MM 156 160 49 30%
|
|
|
+ * 10 000 10K 1 ED 139 154 55 35%
|
|
|
+ * 100 000 1 000M 10K LL 392 361 90 25%
|
|
|
+ *
|
|
|
+ * String:
|
|
|
+ * SIZE DOMAIN 1/HIT NAME TREE SWITCH HASH RATIO
|
|
|
+ * 32 1K 30 TT 95 96 69 71%
|
|
|
+ * 256 1K 4 SS 123 133 72 54%
|
|
|
+ * 256 100K 400 SM 128 135 73 54%
|
|
|
+ * 256 1 000M 4M SL 146 152 78 51%
|
|
|
+ * 10 000 1 000M 100K MM 292 316 98 31%
|
|
|
+ * 10 000 10K 1 ED 249 261 113 43%
|
|
|
+ * 100 000 1 000M 10K LL 753 723 169 23%
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * SUMMARY:
|
|
|
+ *
|
|
|
+ * TREE SWITCH HASH RATIO
|
|
|
+ * Integer 981 980 353 34%
|
|
|
+ * String 1786 1816 672 36%
|
|
|
+ *
|
|
|
+ * CONCLUSION:
|
|
|
+ * it is classical O(logN) performance identical to TreeMap
|
|
|
+ * it is better in terms of memory usage but slower than HashMap
|
|
|
+ *
|
|
|
+ * difference is observable for every N (even for N=32 hash is 30% better)
|
|
|
+ * its acceptable choice anyway
|
|
|
+ *
|
|
|
+ * @author ranides
|
|
|
+ */
|
|
|
+public class SwitchMapBenchmark extends SimpleBenchmark {
|
|
|
+
|
|
|
+ private IntMaps intTT;
|
|
|
+ private IntMaps intSS;
|
|
|
+ private IntMaps intSM;
|
|
|
+ private IntMaps intSL;
|
|
|
+ private IntMaps intMM;
|
|
|
+ private IntMaps intLL;
|
|
|
+ private IntMaps intED;
|
|
|
+
|
|
|
+ private StrMaps strTT;
|
|
|
+ private StrMaps strSS;
|
|
|
+ private StrMaps strSM;
|
|
|
+ private StrMaps strSL;
|
|
|
+ private StrMaps strMM;
|
|
|
+ private StrMaps strLL;
|
|
|
+ private StrMaps strED;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setUp() {
|
|
|
+ intTT = new IntMaps( 32, 1_000 );
|
|
|
+ intSS = new IntMaps( 256, 1_000 );
|
|
|
+ intSM = new IntMaps( 256, 100_000 );
|
|
|
+ intSL = new IntMaps( 256, 1_000_000_000 );
|
|
|
+ intMM = new IntMaps( 10_000, 1_000_000_000 );
|
|
|
+ intLL = new IntMaps(100_000, 1_000_000_000 );
|
|
|
+ intED = new IntMaps( 10_000, 10_000 );
|
|
|
+
|
|
|
+ strTT = new StrMaps( 32, 1_000 );
|
|
|
+ strSS = new StrMaps( 256, 1_000 );
|
|
|
+ strSM = new StrMaps( 256, 100_000 );
|
|
|
+ strSL = new StrMaps( 256, 1_000_000_000 );
|
|
|
+ strMM = new StrMaps( 10_000, 1_000_000_000 );
|
|
|
+ strLL = new StrMaps(100_000, 1_000_000_000 );
|
|
|
+ strED = new StrMaps( 10_000, 10_000 );
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class IntMaps {
|
|
|
+
|
|
|
+ public final int domain;
|
|
|
+ public final SortedMap<Integer,Character> tree;
|
|
|
+ public final Map<Integer,Character> smap;
|
|
|
+ public final Map<Integer,Character> hash;
|
|
|
+
|
|
|
+ public IntMaps(int n, int domain) {
|
|
|
+ this.domain = domain;
|
|
|
+ this.tree = new TreeMap<>();
|
|
|
+ for(int i=0; i<n; i++) {
|
|
|
+ int key = Randomizer.number(domain);
|
|
|
+ char val = Randomizer.character();
|
|
|
+ this.tree.put(key, val);
|
|
|
+ }
|
|
|
+ this.smap = new SwitchMap<>(tree);
|
|
|
+ this.hash = new HashMap<>(tree);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final class StrMaps {
|
|
|
+
|
|
|
+ public final int domain;
|
|
|
+ public final SortedMap<String,Character> tree;
|
|
|
+ public final Map<String,Character> smap;
|
|
|
+ public final Map<String,Character> hash;
|
|
|
+
|
|
|
+ public StrMaps(int n, int domain) {
|
|
|
+ this.domain = domain;
|
|
|
+ this.tree = new TreeMap<>();
|
|
|
+ for(int i=0; i<n; i++) {
|
|
|
+ String key = Integer.toHexString(Randomizer.number(domain));
|
|
|
+ char val = Randomizer.character();
|
|
|
+ this.tree.put(key, val);
|
|
|
+ }
|
|
|
+ this.smap = new SwitchMap<>(tree);
|
|
|
+ this.hash = new HashMap<>(tree);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private int itimeIntMap(int reps, int domain, Map<Integer, Character> map) {
|
|
|
+ int c = 0;
|
|
|
+ for(int i=0; i<reps; i++) {
|
|
|
+ int key = Randomizer.number(domain);
|
|
|
+ Character val = map.get(key);
|
|
|
+ c += (null == val) ? 1 : 2;
|
|
|
+ }
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int itimeStrMap(int reps, int domain, Map<String, Character> map) {
|
|
|
+ int c = 0;
|
|
|
+ for(int i=0; i<reps; i++) {
|
|
|
+ String key = Long.toHexString(Randomizer.number(domain));
|
|
|
+ Character val = map.get(key);
|
|
|
+ c += (null == val) ? 1 : 2;
|
|
|
+ }
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+//
|
|
|
+// public int timeIntSS_tree(int reps) {
|
|
|
+// return itimeIntMap(reps, intSS.domain, intSS.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntSM_tree(int reps) {
|
|
|
+// return itimeIntMap(reps, intSM.domain, intSM.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntSL_tree(int reps) {
|
|
|
+// return itimeIntMap(reps, intSL.domain, intSL.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntMM_tree(int reps) {
|
|
|
+// return itimeIntMap(reps, intMM.domain, intMM.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntLL_tree(int reps) {
|
|
|
+// return itimeIntMap(reps, intLL.domain, intLL.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntSS_hash(int reps) {
|
|
|
+// return itimeIntMap(reps, intSS.domain, intSS.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntSM_hash(int reps) {
|
|
|
+// return itimeIntMap(reps, intSM.domain, intSM.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntSL_hash(int reps) {
|
|
|
+// return itimeIntMap(reps, intSL.domain, intSL.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntMM_hash(int reps) {
|
|
|
+// return itimeIntMap(reps, intMM.domain, intMM.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntLL_hash(int reps) {
|
|
|
+// return itimeIntMap(reps, intLL.domain, intLL.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntSS_smap(int reps) {
|
|
|
+// return itimeIntMap(reps, intSS.domain, intSS.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntSM_smap(int reps) {
|
|
|
+// return itimeIntMap(reps, intSM.domain, intSM.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntSL_smap(int reps) {
|
|
|
+// return itimeIntMap(reps, intSL.domain, intSL.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntMM_smap(int reps) {
|
|
|
+// return itimeIntMap(reps, intMM.domain, intMM.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntED_smap(int reps) {
|
|
|
+// return itimeIntMap(reps, intED.domain, intED.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntED_tree(int reps) {
|
|
|
+// return itimeIntMap(reps, intED.domain, intED.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeIntED_hash(int reps) {
|
|
|
+// return itimeIntMap(reps, intED.domain, intED.hash);
|
|
|
+// }
|
|
|
+
|
|
|
+ public int timeIntTT_smap(int reps) {
|
|
|
+ return itimeIntMap(reps, intTT.domain, intTT.smap);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int timeIntTT_tree(int reps) {
|
|
|
+ return itimeIntMap(reps, intTT.domain, intTT.tree);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int timeIntTT_hash(int reps) {
|
|
|
+ return itimeIntMap(reps, intTT.domain, intTT.hash);
|
|
|
+ }
|
|
|
+
|
|
|
+//
|
|
|
+// public int timeStrSS_tree(int reps) {
|
|
|
+// return itimeStrMap(reps, strSS.domain, strSS.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrSM_tree(int reps) {
|
|
|
+// return itimeStrMap(reps, strSM.domain, strSM.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrSL_tree(int reps) {
|
|
|
+// return itimeStrMap(reps, strSL.domain, strSL.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrMM_tree(int reps) {
|
|
|
+// return itimeStrMap(reps, strMM.domain, strMM.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrLL_tree(int reps) {
|
|
|
+// return itimeStrMap(reps, strLL.domain, strLL.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrSS_hash(int reps) {
|
|
|
+// return itimeStrMap(reps, strSS.domain, strSS.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrSM_hash(int reps) {
|
|
|
+// return itimeStrMap(reps, strSM.domain, strSM.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrSL_hash(int reps) {
|
|
|
+// return itimeStrMap(reps, strSL.domain, strSL.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrMM_hash(int reps) {
|
|
|
+// return itimeStrMap(reps, strMM.domain, strMM.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrLL_hash(int reps) {
|
|
|
+// return itimeStrMap(reps, strLL.domain, strLL.hash);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrSS_smap(int reps) {
|
|
|
+// return itimeStrMap(reps, strSS.domain, strSS.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrSM_smap(int reps) {
|
|
|
+// return itimeStrMap(reps, strSM.domain, strSM.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrSL_smap(int reps) {
|
|
|
+// return itimeStrMap(reps, strSL.domain, strSL.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrMM_smap(int reps) {
|
|
|
+// return itimeStrMap(reps, strMM.domain, strMM.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrLL_smap(int reps) {
|
|
|
+// return itimeStrMap(reps, strLL.domain, strLL.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrED_smap(int reps) {
|
|
|
+// return itimeStrMap(reps, strED.domain, strED.smap);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrED_tree(int reps) {
|
|
|
+// return itimeStrMap(reps, strED.domain, strED.tree);
|
|
|
+// }
|
|
|
+//
|
|
|
+// public int timeStrED_hash(int reps) {
|
|
|
+// return itimeStrMap(reps, strED.domain, strED.hash);
|
|
|
+// }
|
|
|
+
|
|
|
+ public int timeStrTT_smap(int reps) {
|
|
|
+ return itimeStrMap(reps, strTT.domain, strTT.smap);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int timeStrTT_tree(int reps) {
|
|
|
+ return itimeStrMap(reps, strTT.domain, strTT.tree);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int timeStrTT_hash(int reps) {
|
|
|
+ return itimeStrMap(reps, strTT.domain, strTT.hash);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ Runner.main(SwitchMapBenchmark.class, args);
|
|
|
+ }
|
|
|
+}
|