Skip to content

Instantly share code, notes, and snippets.

@erickj
Last active February 26, 2018 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erickj/30aa179a73ab1e2a2b7355b63a34b487 to your computer and use it in GitHub Desktop.
Save erickj/30aa179a73ab1e2a2b7355b63a34b487 to your computer and use it in GitHub Desktop.
TraversalBench...
Run 1: g.V().outE()
!!!
!!! Java Native traversal !!!
!!!
warmup(10) done in:
total: 19.133056ms
per iteration: 1.913306ms
warmup(100) done in:
total: 28.484113ms
per iteration: 0.284841ms
warmup(1000) done in:
total: 125.944196ms
per iteration: 0.125944ms
result time: 0.154849ms
!!!
!!! Script Engine traversal !!!
!!!
warmup(10) done in:
total: 50.031126ms
per iteration: 5.003113ms
warmup(100) done in:
total: 23.731849ms
per iteration: 0.237318ms
warmup(1000) done in:
total: 125.819753ms
per iteration: 0.125820ms
result time: 0.144291ms
!!!
!!! Bytecode traversal !!!
!!!
warmup(10) done in:
total: 1.997528ms
per iteration: 0.199753ms
warmup(100) done in:
total: 5.947392ms
per iteration: 0.059474ms
warmup(1000) done in:
total: 62.082170ms
per iteration: 0.062082ms
result time: 0.128680ms
TraversalBench...
Run 1: g.V(1).out('knows').values('name')
!!!
!!! Java Native traversal !!!
!!!
warmup(10) done in:
total: 6.695467ms
per iteration: 0.669547ms
warmup(100) done in:
total: 11.061351ms
per iteration: 0.110614ms
warmup(1000) done in:
total: 53.746260ms
per iteration: 0.053746ms
result time: 0.083552ms
!!!
!!! Script Engine traversal !!!
!!!
warmup(10) done in:
total: 36.414791ms
per iteration: 3.641479ms
warmup(100) done in:
total: 12.565176ms
per iteration: 0.125652ms
warmup(1000) done in:
total: 97.489639ms
per iteration: 0.097490ms
result time: 0.159088ms
!!!
!!! Bytecode traversal !!!
!!!
warmup(10) done in:
total: 1.179642ms
per iteration: 0.117964ms
warmup(100) done in:
total: 11.532068ms
per iteration: 0.115321ms
warmup(1000) done in:
total: 79.734606ms
per iteration: 0.079735ms
result time: 0.091599ms
TraversalBench...
Run 3: g.V().hasLabel('person').choose(values('age').is(lte(30)), __.in(), __.out()).values('name')
!!!
!!! Java Native traversal !!!
!!!
warmup(10) done in:
total: 39.137261ms
per iteration: 3.913726ms
warmup(100) done in:
total: 72.466179ms
per iteration: 0.724662ms
warmup(1000) done in:
total: 236.760206ms
per iteration: 0.236760ms
result time: 0.353925ms
!!!
!!! Script Engine traversal !!!
!!!
warmup(10) done in:
total: 24.835064ms
per iteration: 2.483506ms
warmup(100) done in:
total: 54.256237ms
per iteration: 0.542562ms
warmup(1000) done in:
total: 254.830645ms
per iteration: 0.254831ms
result time: 0.396736ms
!!!
!!! Bytecode traversal !!!
!!!
warmup(10) done in:
total: 6.961101ms
per iteration: 0.696110ms
warmup(100) done in:
total: 31.017225ms
per iteration: 0.310172ms
warmup(1000) done in:
total: 198.093553ms
per iteration: 0.198094ms
result time: 0.355522ms
TraversalBench...
Run 4: g.V().has('name','marko').repeat(out()).times(2).groupCount().by('name')
!!!
!!! Java Native traversal !!!
!!!
warmup(10) done in:
total: 5.775404ms
per iteration: 0.577540ms
warmup(100) done in:
total: 33.639707ms
per iteration: 0.336397ms
warmup(1000) done in:
total: 104.268361ms
per iteration: 0.104268ms
result time: 0.144245ms
!!!
!!! Script Engine traversal !!!
!!!
warmup(10) done in:
total: 9.762038ms
per iteration: 0.976204ms
warmup(100) done in:
total: 24.413798ms
per iteration: 0.244138ms
warmup(1000) done in:
total: 159.212410ms
per iteration: 0.159212ms
result time: 0.246301ms
!!!
!!! Bytecode traversal !!!
!!!
warmup(10) done in:
total: 3.752110ms
per iteration: 0.375211ms
warmup(100) done in:
total: 29.596277ms
per iteration: 0.295963ms
warmup(1000) done in:
total: 123.809216ms
per iteration: 0.123809ms
result time: 0.224183ms
TraversalBench...
Run 1: g.V().outE()
!!!
!!! Java Native traversal !!!
!!!
warmup(10) done in:
total: 23.722339ms
per iteration: 2.372234ms
warmup(100) done in:
total: 29.206641ms
per iteration: 0.292066ms
warmup(1000) done in:
total: 127.089622ms
per iteration: 0.127090ms
result time: 0.174406ms
!!!
!!! Script Engine traversal !!!
!!!
warmup(10) done in:
total: 47.175194ms
per iteration: 4.717519ms
warmup(100) done in:
total: 36.383286ms
per iteration: 0.363833ms
warmup(1000) done in:
total: 140.792184ms
per iteration: 0.140792ms
result time: 0.166214ms
!!!
!!! Bytecode traversal !!!
!!!
warmup(10) done in:
total: 21.872346ms
per iteration: 2.187235ms
warmup(100) done in:
total: 138.714526ms
per iteration: 1.387145ms
warmup(1000) done in:
total: 516.724577ms
per iteration: 0.516725ms
result time: 0.485695ms
TraversalBench...
Run 1: g.V(1).out('knows').values('name')
!!!
!!! Java Native traversal !!!
!!!
warmup(10) done in:
total: 7.586529ms
per iteration: 0.758653ms
warmup(100) done in:
total: 8.740898ms
per iteration: 0.087409ms
warmup(1000) done in:
total: 67.843517ms
per iteration: 0.067844ms
result time: 0.080826ms
!!!
!!! Script Engine traversal !!!
!!!
warmup(10) done in:
total: 55.004259ms
per iteration: 5.500426ms
warmup(100) done in:
total: 16.308394ms
per iteration: 0.163084ms
warmup(1000) done in:
total: 133.953688ms
per iteration: 0.133954ms
result time: 0.207327ms
!!!
!!! Bytecode traversal !!!
!!!
warmup(10) done in:
total: 7.260053ms
per iteration: 0.726005ms
warmup(100) done in:
total: 63.388740ms
per iteration: 0.633887ms
warmup(1000) done in:
total: 445.554497ms
per iteration: 0.445554ms
result time: 0.463575ms
TraversalBench...
Run 3: g.V().hasLabel('person').choose(values('age').is(lte(30)), __.in(), __.out()).values('name')
!!!
!!! Java Native traversal !!!
!!!
warmup(10) done in:
total: 31.304910ms
per iteration: 3.130491ms
warmup(100) done in:
total: 68.511333ms
per iteration: 0.685113ms
warmup(1000) done in:
total: 293.160874ms
per iteration: 0.293161ms
result time: 0.289666ms
!!!
!!! Script Engine traversal !!!
!!!
warmup(10) done in:
total: 23.613168ms
per iteration: 2.361317ms
warmup(100) done in:
total: 52.100115ms
per iteration: 0.521001ms
warmup(1000) done in:
total: 235.183739ms
per iteration: 0.235184ms
result time: 0.346527ms
!!!
!!! Bytecode traversal !!!
!!!
warmup(10) done in:
total: 39.361747ms
per iteration: 3.936175ms
warmup(100) done in:
total: 137.304990ms
per iteration: 1.373050ms
warmup(1000) done in:
total: 987.066920ms
per iteration: 0.987067ms
result time: 1.086295ms
TraversalBench...
Run 4: g.V().has('name','marko').repeat(out()).times(2).groupCount().by('name')
!!!
!!! Java Native traversal !!!
!!!
warmup(10) done in:
total: 7.924316ms
per iteration: 0.792432ms
warmup(100) done in:
total: 30.954189ms
per iteration: 0.309542ms
warmup(1000) done in:
total: 139.285917ms
per iteration: 0.139286ms
result time: 0.177736ms
!!!
!!! Script Engine traversal !!!
!!!
warmup(10) done in:
total: 8.691457ms
per iteration: 0.869146ms
warmup(100) done in:
total: 23.694427ms
per iteration: 0.236944ms
warmup(1000) done in:
total: 165.945313ms
per iteration: 0.165945ms
result time: 0.214160ms
!!!
!!! Bytecode traversal !!!
!!!
warmup(10) done in:
total: 6.351670ms
per iteration: 0.635167ms
warmup(100) done in:
total: 75.253326ms
per iteration: 0.752533ms
warmup(1000) done in:
total: 522.935322ms
per iteration: 0.522935ms
result time: 0.638993ms
package io.vos.graphs;
import static org.apache.tinkerpop.gremlin.process.traversal.P.lte;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.in;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.out;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.values;
import org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
import org.apache.tinkerpop.gremlin.jsr223.JavaTranslator;
import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.io.IoCore;
import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
class TraversalBench {
private static final Graph graph = TinkerFactory.createModern();
private static final GraphTraversalSource g = graph.traversal();
private static final boolean TIMED_COMPILE = true;
public static void main(String[] args) {
run1();
run2();
run3();
run4();
}
static void run1() {
System.out.println("TraversalBench...");
System.out.println("Run 1: g.V().outE()");
List<?> javaNativeResults = runJavaNativeTraversal(g.V().outE());
List<?> groovyResults = runGroovyTraversal("g.V().outE()");
List<?> bytecodeResults = runBytecodeTraversal(g.V().outE());
assertResultsMatch(javaNativeResults, groovyResults, bytecodeResults);
}
static void run2() {
System.out.println("TraversalBench...");
System.out.println("Run 1: g.V(1).out('knows').values('name')");
List<?> javaNativeResults = runJavaNativeTraversal(g.V(1).out("knows").values("name"));
List<?> groovyResults = runGroovyTraversal("g.V(1).out('knows').values('name')");
List<?> bytecodeResults = runBytecodeTraversal(g.V(1).out("knows").values("name"));
assertResultsMatch(javaNativeResults, groovyResults, bytecodeResults);
}
static void run3() {
System.out.println("TraversalBench...");
System.out.println("Run 3: g.V().hasLabel('person').choose(values('age').is(lte(30)), __.in(), __.out()).values('name')");
List<?> javaNativeResults = runJavaNativeTraversal(
g.V().hasLabel("person").choose(values("age").is(lte(30)), in(), out()).values("name"));
List<?> groovyResults = runGroovyTraversal(
"g.V().hasLabel('person').choose(values('age').is(lte(30)), __.in(), __.out()).values('name')");
List<?> bytecodeResults = runBytecodeTraversal(
g.V().hasLabel("person").choose(values("age").is(lte(30)), in(), out()).values("name"));
assertResultsMatch(javaNativeResults, groovyResults, bytecodeResults);
}
static void run4() {
System.out.println("TraversalBench...");
System.out.println("Run 4: g.V().has('name','marko').repeat(out()).times(2).groupCount().by('name')");
List<?> javaNativeResults = runJavaNativeTraversal(
g.V().has("name","marko").repeat(out()).times(2).groupCount().by("name"));
List<?> groovyResults = runGroovyTraversal(
"g.V().has('name','marko').repeat(out()).times(2).groupCount().by('name')");
List<?> bytecodeResults = runBytecodeTraversal(
g.V().has("name","marko").repeat(out()).times(2).groupCount().by("name"));
assertResultsMatch(javaNativeResults, groovyResults, bytecodeResults);
}
/**
* Serialization method group threads:
* https://groups.google.com/forum/#!topic/gremlin-users/0HCWv1Zlsw8 (marko's email: JavaTranslator vs. GroovyTranslator and Gremlin bytecode compilation speeds)
* https://groups.google.com/forum/#!msg/gremlin-users/R7qQbJXWcH8/iEcvJaVVBAAJ (marko's email: Traveral ByteCode and Translators)
* https://groups.google.com/forum/#!topic/gremlin-users/UuxzWQTl1x4 (how to convert dsl script to Traversal bytecode)
*
*/
static List<?> runJavaNativeTraversal(GraphTraversal<?, ?> t) {
System.out.println("!!!");
System.out.println("!!! Java Native traversal !!!");
System.out.println("!!!");
return TraversalBench.<List<?>>runIterations(() -> {
GraphTraversal.Admin<?, ?> adminClone = t.asAdmin().clone();
return adminClone.toList();
});
}
/**
* Groovy Script engine:
* http://tinkerpop.apache.org/javadocs/current/full/org/apache/tinkerpop/gremlin/groovy/jsr223/GremlinGroovyScriptEngine.html
*
* https://docs.oracle.com/javase/7/docs/api/javax/script/ScriptEngine.html#eval(java.lang.String)
*/
static List<?> runGroovyTraversal(String t) {
System.out.println("!!!");
System.out.println("!!! Script Engine traversal !!!");
System.out.println("!!!");
CompiledScript precompiled;
GremlinGroovyScriptEngine e = new GremlinGroovyScriptEngine();
try {
precompiled = e.compile(t + ".toList()");
} catch (ScriptException ex) {
throw new RuntimeException(ex);
}
List<?> result = (List<?>)TraversalBench.<Object>runIterations(() -> {
e.put("g", g);
if (TIMED_COMPILE) {
return e.eval(t + ".toList()");
}
return precompiled.eval();
});
try {
e.close();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
return result;
}
/**
* See tinerpop gremlin-server:
* https://github.com/apache/tinkerpop/blob/master/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/op/traversal/TraversalOpProcessor.java#L367
* https://github.com/apache/tinkerpop/blob/master/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/message/RequestMessage.java
*
* Graph Traversal Serialization:
* https://github.com/apache/tinkerpop/blob/master/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/structure/io/type-serializers.js
* http://tinkerpop.apache.org/docs/current/dev/io/#_bytecode_2
*
* GraphSON:
* http://tinkerpop.apache.org/javadocs/current/core/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.html
* http://tinkerpop.apache.org/javadocs/current/core/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.html
*/
static List<?> runBytecodeTraversal(GraphTraversal<?, ?> t) {
System.out.println("!!!");
System.out.println("!!! Bytecode traversal !!!");
System.out.println("!!!");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
graph.io(IoCore.graphson()).writer().create().writeObject(bos, t);
} catch (Exception ex) {
System.out.println("error serializing traversal: " + ex);
}
byte[] bytecodeData = bos.toByteArray();
GraphSONReader graphsonReader = graph.io(IoCore.graphson()).reader().create();
Bytecode btcFromJson;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(bytecodeData);
btcFromJson = graphsonReader.readObject(bis, Bytecode.class);
bis.close();
bos.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
return TraversalBench.<List<?>>runIterations(
() -> {
if (TIMED_COMPILE) {
Bytecode timedJson = graphsonReader.readObject(
new ByteArrayInputStream(bytecodeData), Bytecode.class);
return JavaTranslator.of(g).translate(timedJson).toList();
}
return JavaTranslator.of(g).translate(btcFromJson).toList();
});
}
static <V> V runIterations(Callable<V> c) {
List<Integer> warmupIterations = new ArrayList<Integer>() {{ add(10); add(100); add(1000); }};
return runMinibench(warmupIterations, c);
}
private static <V> V runMinibench(List<Integer> warmupIterations, Callable<V> c) {
for (Integer iterations : warmupIterations) {
long startWarmup = System.nanoTime();
for (int i = 0; i < iterations; i++) {
try {
c.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
long endWarmup = System.nanoTime();
System.out.println(
String.format(
"warmup(%d) done in: \n\ttotal: %fms\n\tper iteration: %fms",
iterations,
(endWarmup - startWarmup) / 1_000_000d,
(endWarmup - startWarmup) / iterations.doubleValue() / 1_000_000d));
}
V result;
long start = System.nanoTime();
try {
result = c.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
long end = System.nanoTime();
System.out.println(String.format("result time: %fms", (end - start) / 1_000_000d));
return result;
}
private static void assertResultsMatch(List<?> r1, List<?> r2, List<?> r3) {
if (r1.isEmpty()) {
throw new AssertionError("r1 is empty");
}
if (r1.size() != r2.size() || r2.size() != r3.size()) {
throw new AssertionError("result set count mismatch");
}
for (int i = 0; i < r1.size(); i++) {
if (!r1.get(i).equals(r2.get(i))
|| !r1.get(i).equals(r3.get(i))) {
System.out.println(r1.get(i));
System.out.println(r2.get(i));
System.out.println(r3.get(i));
throw new AssertionError("object mismatch");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment