Skip to content

Instantly share code, notes, and snippets.

Created March 7, 2013 18:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/5110608 to your computer and use it in GitHub Desktop.
Save anonymous/5110608 to your computer and use it in GitHub Desktop.
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MicroBenchmark {
public static final int ITERATIONS = 100000;
public static final int SIZE = 10;
public static final StringBuffer stash1 = new StringBuffer(SIZE*22);
public static final StringBuffer stash2 = new StringBuffer(SIZE*22);
public static void main(String[] args) throws InterruptedException {
System.gc();
Thread.sleep(1000);
long mapTime = 0;
for (int i = 0; i < ITERATIONS; i++) {
mapTime += maps(SIZE);
}
System.gc();
Thread.sleep(1000);
long tableTime = 0;
for (int i = 0; i < ITERATIONS; i++) {
tableTime += table(SIZE);
}
System.out.println("Maps took (ms):" + mapTime);
System.out.println("Table took (ms):" + tableTime);
}
public static long maps(int size) {
long start = System.currentTimeMillis();
DataSet data = buildData(size);
Map<String, String> fullNameById = buildMap1(data);
Map<String, String> nameById = buildMap2(data);
Map<String, String> nameByFullName = new HashMap<String, String>();
Map<String, String> idByName = new HashMap<String, String>();
Set<String> ids = fullNameById.keySet();
for (String nextId : ids) {
String name = nameById.get(nextId);
String fullName = fullNameById.get(nextId);
nameByFullName.put(fullName, name);
idByName.put(name, nextId);
}
// Prevent compiler from throwing away code that isn't used.
stash1.append(nameByFullName.get(data.ids[0]));
stash1.append(idByName.get(data.names[0]));
long end = System.currentTimeMillis();
return end - start;
}
public static long table(int size) {
long start = System.currentTimeMillis();
Table<String, String, String> relations = HashBasedTable.create();
DataSet data = buildData(size);
addRelationships1(relations, data);
addRelationships2(relations, data);
Map<String, String> idByName = relations.column("hasId");
Map<String, String> nameByFullName = relations.column("hasName");
// Prevent compiler from throwing away code that isn't used.
stash2.append(nameByFullName.get(data.ids[0]));
stash2.append(idByName.get(data.names[0]));
long end = System.currentTimeMillis();
return end - start;
}
private static void addRelationships1(Table<String, String, String> rels, DataSet data) {
for (int i = 0; i < data.size; i++) {
rels.put(data.ids[i], "hasFullName", data.fullNames[i]);
}
}
public static Map<String, String> buildMap1(DataSet data) {
HashMap<String, String> result = new HashMap<String, String>();
for (int i = 0; i < data.size; i++) {
result.put(data.ids[i], data.fullNames[i]);
}
return result;
}
public static Map<String, String> buildMap2(DataSet data) {
HashMap<String, String> result = new HashMap<String, String>();
for (int i = 0; i < data.size; i++) {
result.put(data.ids2[i], data.names[i]);
}
return result;
}
public static void addRelationships2(Table<String, String, String> rels, DataSet data) {
for (int i = 0; i < data.size; i++) {
String name = data.names[i];
String id = data.ids2[i];
rels.put(rels.remove(id, "hasFullName"), "hasName", name);
rels.put(name, "hasId", id);
}
}
private static String get10digitoctal() {
// format as octal to avoid localization overhead, 10 digits zero padded to provide consistent data size
// important to generate new unique strings to avoid caching of hashcode value.
return String.format("%010o", (long) (Math.random() * Long.MAX_VALUE));
}
public static DataSet buildData(int size) {
DataSet result = new DataSet(size);
for (int i = 0; i < size; i++) {
result.names[i] = get10digitoctal();
}
for (int i = 0; i < size; i++) {
result.fullNames[i] = get10digitoctal();
}
for (int i = 0; i < size; i++) {
result.ids[i] = get10digitoctal();
}
// must be the same values, but new string objects with uncached hash codes, simulating data
// read from a different connection.
for (int i = 0; i < size; i++) {
result.ids2[i] = new String(result.ids[i]);
}
return result;
}
public static class DataSet {
public int size;
public String[] names;
public String[] fullNames;
public String[] ids;
public String[] ids2;
public DataSet(int size) {
this.size = size;
this.names = new String[size];
this.fullNames = new String[size];
this.ids = new String[size];
this.ids2 = new String[size];
}
}
}
/*
Case Maps (ms) Tables (ms) Tables vs Maps
100000 runs of size 10 2931 3035 104%
10000 runs of size 100 2989 3033 101%
1000 runs of size 1000 3129 3160 101%
100 runs of size 10000 4126 4429 107%
10 runs of size 100000 5081 5866 115%
1 run of size 1000000 5489 5160 94%
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment