/* * Copyright (c) 2002-2017 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Licensed 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.neo4j.driver.v1.stress; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.neo4j.driver.v1.Driver; import org.neo4j.driver.v1.GraphDatabase; import org.neo4j.driver.v1.Session; import org.neo4j.driver.v1.StatementResult; import org.neo4j.driver.v1.Value; import org.neo4j.driver.v1.util.Neo4jRunner; import org.neo4j.driver.v1.util.Neo4jSettings; import static org.neo4j.driver.v1.Values.parameters; public class DriverStresser { private static Neo4jRunner server; private static Driver driver; public static void main( String... args ) throws Throwable { int iterations = 100_000; bench( iterations, 1, 10_000 ); bench( (long) iterations / 2, 2, 10_000 ); bench( (long) iterations / 4, 4, 10_000 ); bench( (long) iterations / 8, 8, 10_000 ); bench( (long) iterations / 16, 16, 10_000 ); bench( (long) iterations / 32, 32, 10_000 ); } public static void setup() throws Exception { server = Neo4jRunner.getOrCreateGlobalRunner(); server.ensureRunning( Neo4jSettings.TEST_SETTINGS ); driver = GraphDatabase.driver( "bolt://localhost:7687" ); } static class Worker { private final Session session; public Worker() { session = driver.session(); } public int operation() { String statement = "RETURN 1 AS n"; // = "CREATE (a {name:{n}}) RETURN a.name"; Value parameters = parameters(); // = Values.parameters( "n", "Bob" ); int total = 0; StatementResult result = session.run( statement, parameters ); while ( result.hasNext() ) { total += result.next().get( "n" ).asInt(); } return total; } } public static void tearDown() throws Exception { driver.close(); server.stopNeo4j(); } private static void bench( long iterations, int concurrency, long warmupIterations ) throws Exception { ExecutorService executorService = Executors.newFixedThreadPool( concurrency ); setup(); try { // Warmup awaitAll( executorService.invokeAll( workers( warmupIterations, concurrency ) ) ); long start = System.nanoTime(); List<Future<Object>> futures = executorService.invokeAll( workers( iterations, concurrency ) ); awaitAll( futures ); long delta = System.nanoTime() - start; System.out.printf( "With %d threads: %s ops/s%n", concurrency, (iterations * concurrency) / (delta / 1_000_000_000.0) ); } finally { tearDown(); } executorService.shutdownNow(); executorService.awaitTermination( 10, TimeUnit.SECONDS ); } private static void awaitAll( List<Future<Object>> futures ) throws Exception { for ( Future<Object> future : futures ) { future.get(); } } private static List<Callable<Object>> workers( final long iterations, final int numWorkers ) { List<Callable<Object>> workers = new ArrayList<>(); for ( int i = 0; i < numWorkers; i++ ) { final Worker worker = new Worker(); workers.add( new Callable<Object>() { @Override public Object call() throws Exception { int dontRemoveMyCode = 0; for ( int i = 0; i < iterations; i++ ) { dontRemoveMyCode += worker.operation(); } return dontRemoveMyCode; } } ); } return workers; } }