Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions src/jmh/java/performance/LargeInMemoryQueryPerformance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package performance;

import benchmark.BenchmarkUtils;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
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 org.openjdk.jmh.profile.GCProfiler;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring;

/**
* This benchmark is an attempt to have a large in memory query that involves only sync work but lots of
* data fetching invocation
* <p>
* It can also be run in a forever mode say if you want to connect a profiler to it say
*/
@State(Scope.Benchmark)
@Warmup(iterations = 2, time = 5)
@Measurement(iterations = 2)
@Fork(2)
public class LargeInMemoryQueryPerformance {

GraphQL graphQL;
volatile boolean shutDown;

@Setup(Level.Trial)
public void setUp() {
shutDown = false;
graphQL = buildGraphQL();
}

@TearDown(Level.Trial)
public void tearDown() {
shutDown = true;
}


@Benchmark
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public Object benchMarkSimpleQueriesThroughput() {
return runManyQueriesToCompletion();
}

@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.SECONDS)
public Object benchMarkSimpleQueriesAvgTime() {
return runManyQueriesToCompletion();
}


public static void main(String[] args) throws Exception {
// just to make sure it's all valid before testing
runAtStartup();

Options opt = new OptionsBuilder()
.include("performance.LargeInMemoryQueryBenchmark")
.addProfiler(GCProfiler.class)
.build();

new Runner(opt).run();
}

private static void runAtStartup() {

LargeInMemoryQueryPerformance complexQueryBenchmark = new LargeInMemoryQueryPerformance();
BenchmarkUtils.runInToolingForSomeTimeThenExit(
complexQueryBenchmark::setUp,
complexQueryBenchmark::runManyQueriesToCompletion,
complexQueryBenchmark::tearDown

);
}


private Object runManyQueriesToCompletion() {
return graphQL.execute(
"query {\n" +
"\n" +
" giveMeLargeResponse {\n" +
" someValue\n" +
" }\n" +
"}"
);
}

private static final List<SomeWrapper> manyObjects = IntStream
.range(0, 10_000_000)
.mapToObj(i -> new SomeWrapper("value #" + i))
.collect(Collectors.toList());

public static class SomeWrapper {
String someValue;

public SomeWrapper(String someValue) {
this.someValue = someValue;
}
}

private GraphQL buildGraphQL() {
TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse("\n" +
"type Query {\n" +
" giveMeLargeResponse: [SomeWrapper]\n" +
"}\n" +
"type SomeWrapper {\n" +
" someValue: String\n" +
"}\n"
);
RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring()
.type(newTypeWiring("Query")
.dataFetcher("giveMeLargeResponse", env -> manyObjects))
.build();
GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, wiring);
return GraphQL.newGraphQL(schema).build();
}
}
Loading