Skip to content

Commit 6937fbb

Browse files
committed
add more performance tests
1 parent 0f5a21f commit 6937fbb

1 file changed

Lines changed: 161 additions & 3 deletions

File tree

src/test/java/performance/OverlappingFieldValidationPerformance.java

Lines changed: 161 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.openjdk.jmh.annotations.Measurement;
2020
import org.openjdk.jmh.annotations.Mode;
2121
import org.openjdk.jmh.annotations.OutputTimeUnit;
22+
import org.openjdk.jmh.annotations.Param;
2223
import org.openjdk.jmh.annotations.Scope;
2324
import org.openjdk.jmh.annotations.Setup;
2425
import org.openjdk.jmh.annotations.State;
@@ -38,15 +39,42 @@
3839
@Fork(3)
3940
public class OverlappingFieldValidationPerformance {
4041

42+
43+
static String schemaSdl = " type Query { viewer: Viewer } interface Abstract { field: Abstract leaf: Int } interface Abstract1 { field: Abstract leaf: Int } interface Abstract2 { field: Abstract leaf: Int }" +
44+
" type Concrete1 implements Abstract1{ field: Abstract leaf: Int} " +
45+
"type Concrete2 implements Abstract2{ field: Abstract leaf: Int} " +
46+
"type Viewer { xingId: XingId } type XingId { firstName: String! lastName: String! }";
47+
4148
@State(Scope.Benchmark)
4249
public static class MyState {
4350

4451
GraphQLSchema schema;
52+
GraphQLSchema schema2;
4553
Document document;
4654

55+
@Param({"2", "10", "100"})
56+
int size;
57+
58+
Document overlapFrag;
59+
Document overlapNoFrag;
60+
Document noOverlapFrag;
61+
Document noOverlapNoFrag;
62+
Document repeatedFields;
63+
Document deepAbstractConcrete;
64+
4765
@Setup
4866
public void setup() {
4967
try {
68+
overlapFrag = makeQuery(size, true, true);
69+
overlapNoFrag = makeQuery(size, true, false);
70+
noOverlapFrag = makeQuery(size, false, true);
71+
noOverlapNoFrag = makeQuery(size, false, false);
72+
repeatedFields = makeRepeatedFieldsQuery(size);
73+
deepAbstractConcrete = makeDeepAbstractConcreteQuery(size);
74+
75+
76+
schema2 = SchemaGenerator.createdMockedSchema(schemaSdl);
77+
5078
String schemaString = PerformanceTestingUtils.loadResource("large-schema-4.graphqls");
5179
String query = PerformanceTestingUtils.loadResource("large-schema-4-query.graphql");
5280
schema = SchemaGenerator.createdMockedSchema(schemaString);
@@ -64,14 +92,58 @@ public void setup() {
6492

6593
@Benchmark
6694
@BenchmarkMode(Mode.AverageTime)
95+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
6796
public void overlappingFieldValidationAbgTime(MyState myState, Blackhole blackhole) {
68-
blackhole.consume(validateQuery(myState.schema, myState.document));
97+
blackhole.consume(validateQuery(myState.schema2, myState.document));
6998
}
7099

71100
@Benchmark
72-
@OutputTimeUnit(TimeUnit.SECONDS)
101+
@BenchmarkMode(Mode.AverageTime)
102+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
73103
public void overlappingFieldValidationThroughput(MyState myState, Blackhole blackhole) {
74-
blackhole.consume(validateQuery(myState.schema, myState.document));
104+
blackhole.consume(validateQuery(myState.schema2, myState.document));
105+
}
106+
107+
@Benchmark
108+
@BenchmarkMode(Mode.AverageTime)
109+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
110+
public void benchmarkRepeatedFields(MyState myState, Blackhole blackhole) {
111+
blackhole.consume(validateQuery(myState.schema2, myState.repeatedFields));
112+
}
113+
114+
@Benchmark
115+
@BenchmarkMode(Mode.AverageTime)
116+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
117+
public void benchmarkOverlapFrag(MyState myState, Blackhole blackhole) {
118+
blackhole.consume(validateQuery(myState.schema2, myState.overlapFrag));
119+
}
120+
121+
@Benchmark
122+
@BenchmarkMode(Mode.AverageTime)
123+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
124+
public void benchmarkOverlapNoFrag(MyState myState, Blackhole blackhole) {
125+
blackhole.consume(validateQuery(myState.schema2, myState.overlapNoFrag));
126+
}
127+
128+
@Benchmark
129+
@BenchmarkMode(Mode.AverageTime)
130+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
131+
public void benchmarkNoOverlapFrag(MyState myState, Blackhole blackhole) {
132+
blackhole.consume(validateQuery(myState.schema2, myState.noOverlapFrag));
133+
}
134+
135+
@Benchmark
136+
@BenchmarkMode(Mode.AverageTime)
137+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
138+
public void benchmarkNoOverlapNoFrag(MyState myState, Blackhole blackhole) {
139+
blackhole.consume(validateQuery(myState.schema2, myState.noOverlapNoFrag));
140+
}
141+
142+
@Benchmark
143+
@BenchmarkMode(Mode.AverageTime)
144+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
145+
public void benchmarkDeepAbstractConcrete(MyState myState, Blackhole blackhole) {
146+
blackhole.consume(validateQuery(myState.schema2, myState.deepAbstractConcrete));
75147
}
76148

77149
private List<ValidationError> validateQuery(GraphQLSchema schema, Document document) {
@@ -83,4 +155,90 @@ private List<ValidationError> validateQuery(GraphQLSchema schema, Document docum
83155
languageTraversal.traverse(document, new RulesVisitor(validationContext, Collections.singletonList(overlappingFieldsCanBeMerged)));
84156
return errorCollector.getErrors();
85157
}
158+
159+
160+
private static Document makeQuery(int size, boolean overlapping, boolean fragments) {
161+
if (fragments) {
162+
return makeQueryWithFragments(size, overlapping);
163+
} else {
164+
return makeQueryWithoutFragments(size, overlapping);
165+
}
166+
}
167+
168+
private static Document makeRepeatedFieldsQuery(int size) {
169+
StringBuilder b = new StringBuilder();
170+
171+
b.append(" query testQuery { viewer { xingId {");
172+
173+
b.append("firstName\n".repeat(Math.max(0, size)));
174+
175+
b.append("} } }");
176+
177+
return Parser.parse(b.toString());
178+
}
179+
180+
181+
private static Document makeQueryWithFragments(int size, boolean overlapping) {
182+
StringBuilder b = new StringBuilder();
183+
184+
for (int i = 1; i <= size; i++) {
185+
if (overlapping) {
186+
b.append(" fragment mergeIdenticalFields" + i + " on Query {viewer { xingId { firstName lastName }}}");
187+
} else {
188+
b.append("fragment mergeIdenticalFields" + i + " on Query {viewer" + i + " { xingId" + i + " { firstName" + i + " lastName" + i + " } }}");
189+
}
190+
191+
b.append("\n\n");
192+
}
193+
194+
b.append("query testQuery {");
195+
for (int i = 1; i <= size; i++) {
196+
b.append("...mergeIdenticalFields" + i + "\n");
197+
}
198+
b.append("}");
199+
return Parser.parse(b.toString());
200+
}
201+
202+
private static Document makeQueryWithoutFragments(int size, boolean overlapping) {
203+
StringBuilder b = new StringBuilder();
204+
205+
b.append("query testQuery {");
206+
207+
for (int i = 1; i <= size; i++) {
208+
if (overlapping) {
209+
b.append(" viewer { xingId { firstName } } ");
210+
} else {
211+
b.append(" viewer" + i + " { xingId" + i + " { firstName" + i + " } } ");
212+
}
213+
214+
b.append("\n\n");
215+
}
216+
217+
b.append("}");
218+
219+
return Parser.parse(b.toString());
220+
}
221+
222+
private static Document makeDeepAbstractConcreteQuery(int depth) {
223+
StringBuilder q = new StringBuilder();
224+
225+
q.append("fragment multiply on Whatever { field { " +
226+
"... on Abstract1 { field { leaf } } " +
227+
"... on Abstract2 { field { leaf } } " +
228+
"... on Concrete1 { field { leaf } } " +
229+
"... on Concrete2 { field { leaf } } } } " +
230+
"query DeepAbstractConcrete { ");
231+
232+
for (int i = 1; i <= depth; i++) {
233+
q.append("field { ...multiply ");
234+
}
235+
236+
for (int i = 1; i <= depth; i++) {
237+
q.append(" }");
238+
}
239+
240+
q.append("\n}");
241+
242+
return Parser.parse(q.toString());
243+
}
86244
}

0 commit comments

Comments
 (0)