diff --git a/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/benchmark/util/AbstractBenchmarkBase2.java b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/benchmark/util/AbstractBenchmarkBase2.java new file mode 100644 index 00000000000..6c3f7e0d33d --- /dev/null +++ b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/benchmark/util/AbstractBenchmarkBase2.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.benchmark.util; + +import org.junit.Test; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.results.format.ResultFormatType; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.ChainedOptionsBuilder; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Base class for all TinkerPop OpenJDK JMH benchmarks. Based upon Netty's approach to running JMH benchmarks + * from JUnit. + * + * @see + * + * @author Ted Wilmes (http://twilmes.org) + */ +//@Warmup(time = 2001, timeUnit = MILLISECONDS, iterations = 3) +//@Measurement(time = 2002, timeUnit = MILLISECONDS, iterations = 5) +@Fork(5) // doesn't work +public abstract class AbstractBenchmarkBase2 { + + protected static final String DEFAULT_BENCHMARK_DIRECTORY = "./benchmarks/"; + protected static final String DEFAULT_JVM_ARGS = "-server -Xms2g -Xmx2g"; + + @Test + public void run() throws Exception { + final String className = getClass().getSimpleName(); + final ChainedOptionsBuilder runnerOptions = new OptionsBuilder() + .include(".*" + className + ".*") + .jvmArgs(getJvmArgs()) // might be useless + .forks(1); + + if (getReportDir() != null) { + final String dtmStr = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); + final String filePath = getReportDir() + className + "-" + dtmStr + ".json"; + final File file = new File(filePath); + if (file.exists()) { + file.delete(); + } else { + file.getParentFile().mkdirs(); + file.createNewFile(); + } + + runnerOptions.resultFormat(ResultFormatType.JSON); + runnerOptions.result(filePath); + } + + new Runner(runnerOptions.build()).run(); + } + + protected String getReportDir() { + return System.getProperty("benchmarkReportDir", DEFAULT_BENCHMARK_DIRECTORY); + } + + protected String[] getJvmArgs() { + return System.getProperty("jvmArgs", DEFAULT_JVM_ARGS).split(" "); + } +} diff --git a/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/gremlin/driver/EmbeddedBenchmark.java b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/gremlin/driver/EmbeddedBenchmark.java new file mode 100644 index 00000000000..6211117b04b --- /dev/null +++ b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/gremlin/driver/EmbeddedBenchmark.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.gremlin.driver; + +import org.apache.tinkerpop.benchmark.util.AbstractBenchmarkBase2; +import org.apache.tinkerpop.gremlin.driver.simple.SimpleClient; +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.Vertex; +import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph; +import org.apache.tinkerpop.gremlin.util.message.ResponseMessage; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.List; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal; + + +//@Warmup(time = 2000, timeUnit = MILLISECONDS) +@Warmup(time = 2001, timeUnit = MILLISECONDS, iterations = 4) +@Measurement(time = 2002, timeUnit = MILLISECONDS, iterations = 4) +@BenchmarkMode(Mode.AverageTime) +public class EmbeddedBenchmark extends AbstractBenchmarkBase2 { + @State(Scope.Thread) + public static class BenchmarkState { + // fields here + Graph graph; + GraphTraversalSource g; + Cluster cluster; + SimpleClient client; + int j = 0; + @Setup(Level.Trial) + public void doSetup() throws Exception { + // +// final Cluster cluster = TestClientFactory.build().create(); +// final SimpleClient client = TestClientFactory.createWebSocketClient(); + // + + graph = TinkerGraph.open(); + g = traversal().withEmbedded(graph); +// Vertex v1 = g.addV("person").property("name","marko").next(); +// Vertex v2 = g.addV("person").property("name","stephen").next(); +// Vertex v3 = g.addV("person").property("name","vadas").next(); + + // Be sure to use a terminating step like next() or iterate() so that the traversal "executes" + // Iterate() does not return any data and is used to just generate side-effects (i.e. write data to the database) +// g.V(v1).addE("knows").to(v2).property("weight",0.75).iterate(); +// g.V(v1).addE("knows").to(v3).property("weight",0.75).iterate(); + + for (int i = 0; i < 1000000; i++) { + g.addV("person").property("name","vadas").next(); + } + } + + @Setup(Level.Invocation) + public void setupInvocation() { +// bytecodeBuffer1.readerIndex(0); +// bytecodeBuffer2.readerIndex(0); +// pBuffer1.readerIndex(0); +// bufferWrite.readerIndex(0); +// bufferWrite.writerIndex(0); + } + + @TearDown(Level.Trial) + public void doTearDown() { +// bytecodeBuffer1.release(); +// bytecodeBuffer2.release(); + } + } + +// @Benchmark + public Long countJ(BenchmarkState state) throws Exception { + Long res = state.g.V().count().next(); + state.j += 1; + System.out.println(state.j); + return res; + } + +// @Benchmark + public List simpleClient(BenchmarkState state) throws Exception { + final List res = state.client.submit("g.V().count()"); + return res; + } + + @Benchmark + public GraphTraversal limit1k(BenchmarkState state) throws Exception { + GraphTraversal res = state.g.V().limit(1000); + state.j += 1; +// System.out.println(state.j); + return res; + } + + @Benchmark + public GraphTraversal limit1m(BenchmarkState state) throws Exception { + GraphTraversal res = state.g.V().limit(1000000); + state.j += 1; +// System.out.println(state.j); + return res; + } +} diff --git a/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/gremlin/driver/RemoteBenchmark.java b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/gremlin/driver/RemoteBenchmark.java new file mode 100644 index 00000000000..e228a81e064 --- /dev/null +++ b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/gremlin/driver/RemoteBenchmark.java @@ -0,0 +1,135 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.gremlin.driver; + +import org.apache.tinkerpop.benchmark.util.AbstractBenchmarkBase2; +import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection; +import org.apache.tinkerpop.gremlin.driver.simple.SimpleClient; +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.Vertex; +import org.apache.tinkerpop.gremlin.util.message.ResponseMessage; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.List; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal; + + +//@Warmup(time = 2000, timeUnit = MILLISECONDS) +@Warmup(time = 2001, timeUnit = MILLISECONDS, iterations = 1) +@Measurement(time = 2002, timeUnit = MILLISECONDS, iterations = 2) +@BenchmarkMode(Mode.AverageTime) +public class RemoteBenchmark extends AbstractBenchmarkBase2 { + @State(Scope.Thread) + public static class BenchmarkState { + // fields here + Graph graph; + GraphTraversalSource g; + Cluster cluster; + SimpleClient client; + int j = 0; + + @Setup(Level.Trial) + public void doSetup() throws Exception { + cluster = Cluster.build("ec2-35-91-97-124.us-west-2.compute.amazonaws.com").port(45940).create(); + g = traversal().withRemote(DriverRemoteConnection.using(cluster, "ggrateful")); +// g.V().drop().iterate(); +// for (int i = 0; i < 5000000; i +// ++) { +// g.addV("person").property("name","vadas").next(); + System.out.println("count: " + g.V().count().next()); +// } + } + + @Setup(Level.Invocation) + public void setupInvocation() { +// bytecodeBuffer1.readerIndex(0); +// bytecodeBuffer2.readerIndex(0); +// pBuffer1.readerIndex(0); +// bufferWrite.readerIndex(0); +// bufferWrite.writerIndex(0); + } + + @TearDown(Level.Trial) + public void doTearDown() throws Exception { +// System.out.println("count before: " + g.V().count().next()); +// g.V().drop().iterate(); + System.out.println("count after: " + g.V().count().next()); + cluster.close(); + g.close(); + } + } + +// @Benchmark + public Long countJ(BenchmarkState state) throws Exception { + Long res = state.g.V().count().next(); + state.j += 1; + System.out.println(state.j); + return res; + } + +// @Benchmark + public List simpleClient(BenchmarkState state) throws Exception { + final List res = state.client.submit("g.V().count()"); + return res; + } + +// @Benchmark + public GraphTraversal limit1k(BenchmarkState state) throws Exception { + GraphTraversal res = state.g.V().limit(1000); + state.j += 1; +// System.out.println(state.j); + return res; + } + + @Benchmark + public GraphTraversal both5(BenchmarkState state) throws Exception { +// List res = state.g.V().repeat(both()).times(5).toList(); + GraphTraversal res = state.g.V().both().both().both(); + while (res.hasNext()) { + res.next(); + } + state.j += 1; +// System.out.println(state.j); + return res; + } + +// @Benchmark + public Long countBoths(BenchmarkState state) throws Exception { + + +// List res = state.g.V().repeat(both()).times(5).toList(); + Long res = state.g.V().both().both().both().count().next(); + state.j += 1; +// System.out.println(state.j); + return res; + } +}