Skip to content

Commit 4779677

Browse files
committed
gnhf #2: Eliminated Builder allocation overhead in ExecutionStepInfo creation (~66K/op), MergedSelectionSet construction (~5.5K/op), and optimized Async.Many.await() for the fully-materialized case by using CompletableFuture.completedFuture() instead of new+complete.
1 parent 8af017b commit 4779677

File tree

5 files changed

+36
-16
lines changed

5 files changed

+36
-16
lines changed

src/main/java/graphql/execution/Async.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,11 @@ public void addObject(Object object) {
197197
public CompletableFuture<List<T>> await() {
198198
commonSizeAssert();
199199

200-
CompletableFuture<List<T>> overallResult = new CompletableFuture<>();
201200
if (cfCount == 0) {
202-
overallResult.complete(materialisedList(array));
203-
} else {
201+
return CompletableFuture.completedFuture(materialisedList(array));
202+
}
203+
CompletableFuture<List<T>> overallResult = new CompletableFuture<>();
204+
{
204205
CompletableFuture<T>[] cfsArr = copyOnlyCFsToArray();
205206
CompletableFuture.allOf(cfsArr)
206207
.whenComplete((ignored, exception) -> {

src/main/java/graphql/execution/ExecutionStepInfo.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,20 @@ public static ExecutionStepInfo.Builder newExecutionStepInfo() {
274274
return new Builder();
275275
}
276276

277+
/**
278+
* Package-private direct construction that bypasses the Builder, avoiding 2 allocations in the hot path.
279+
*/
280+
static ExecutionStepInfo newExecutionStepInfoDirect(
281+
GraphQLOutputType type,
282+
ResultPath path,
283+
ExecutionStepInfo parent,
284+
MergedField field,
285+
GraphQLFieldDefinition fieldDefinition,
286+
GraphQLObjectType fieldContainer,
287+
Supplier<ImmutableMapWithNullValues<String, Object>> arguments) {
288+
return new ExecutionStepInfo(type, path, parent, field, fieldDefinition, fieldContainer, arguments);
289+
}
290+
277291
public static ExecutionStepInfo.Builder newExecutionStepInfo(ExecutionStepInfo existing) {
278292
return new Builder(existing);
279293
}

src/main/java/graphql/execution/ExecutionStepInfoFactory.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.util.Map;
1919
import java.util.function.Supplier;
2020

21-
import static graphql.execution.ExecutionStepInfo.newExecutionStepInfo;
2221

2322
@Internal
2423
@NullMarked
@@ -57,15 +56,15 @@ public ExecutionStepInfo createExecutionStepInfo(ExecutionContext executionConte
5756
}
5857

5958

60-
return newExecutionStepInfo()
61-
.type(fieldType)
62-
.fieldDefinition(fieldDefinition)
63-
.fieldContainer(fieldContainer)
64-
.field(field)
65-
.path(parameters.getPath())
66-
.parentInfo(parentStepInfo)
67-
.arguments(argumentValues)
68-
.build();
59+
return ExecutionStepInfo.newExecutionStepInfoDirect(
60+
fieldType,
61+
parameters.getPath(),
62+
parentStepInfo,
63+
field,
64+
fieldDefinition,
65+
fieldContainer,
66+
argumentValues
67+
);
6968
}
7069

7170
@NonNull

src/main/java/graphql/execution/FieldCollector.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.Map;
2323
import java.util.Set;
2424

25-
import static graphql.execution.MergedSelectionSet.newMergedSelectionSet;
2625
import static graphql.execution.TypeFromAST.getTypeFromAST;
2726

2827
/**
@@ -46,7 +45,7 @@ public MergedSelectionSet collectFields(FieldCollectorParameters parameters, Mer
4645
this.collectFields(parameters, field.getSelectionSet(), visitedFragments, subFields, null, incrementalSupport);
4746
}
4847
});
49-
return newMergedSelectionSet().subFields(subFields).build();
48+
return MergedSelectionSet.newMergedSelectionSetDirect(subFields);
5049
}
5150

5251
/**
@@ -65,7 +64,7 @@ public MergedSelectionSet collectFields(FieldCollectorParameters parameters, Sel
6564
Map<String, MergedField> subFields = new LinkedHashMap<>();
6665
Set<String> visitedFragments = new LinkedHashSet<>();
6766
this.collectFields(parameters, selectionSet, visitedFragments, subFields, null, incrementalSupport);
68-
return newMergedSelectionSet().subFields(subFields).build();
67+
return MergedSelectionSet.newMergedSelectionSetDirect(subFields);
6968
}
7069

7170

src/main/java/graphql/execution/MergedSelectionSet.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ public static Builder newMergedSelectionSet() {
5252
return new Builder();
5353
}
5454

55+
/**
56+
* Package-private direct construction that bypasses the Builder, avoiding 1 allocation in the hot path.
57+
*/
58+
static MergedSelectionSet newMergedSelectionSetDirect(Map<String, MergedField> subFields) {
59+
return new MergedSelectionSet(subFields);
60+
}
61+
5562
public static class Builder {
5663

5764
private Map<String, MergedField> subFields;

0 commit comments

Comments
 (0)