Skip to content

Commit a9aeb50

Browse files
committed
gnhf #16: Eliminated redundant parentType extraction in completeField by passing it from resolveFieldWithInfo (~66K getUnwrappedNonNullTypeAs calls/op saved), and hoisted loop-invariant type computation and getter calls out of completeValueForList's per-element loop.
1 parent f9b8ade commit a9aeb50

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

src/main/java/graphql/execution/ExecutionStrategy.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
import graphql.schema.GraphQLCodeRegistry;
4040
import graphql.schema.GraphQLEnumType;
4141
import graphql.schema.GraphQLFieldDefinition;
42+
import graphql.schema.GraphQLList;
4243
import graphql.schema.GraphQLObjectType;
44+
import graphql.schema.GraphQLOutputType;
4345
import graphql.schema.GraphQLScalarType;
4446
import graphql.schema.GraphQLSchema;
4547
import graphql.schema.GraphQLType;
@@ -489,7 +491,7 @@ protected Object resolveFieldWithInfo(ExecutionContext executionContext, Executi
489491
if (!executionContext.isNoOpDataLoaderDispatch()) {
490492
executionContext.getDataLoaderDispatcherStrategy().startComplete(parameters);
491493
}
492-
FieldValueInfo completeFieldResult = completeField(fieldDef, executionContext, parameters, fetchedValue);
494+
FieldValueInfo completeFieldResult = completeField(fieldDef, parentType, executionContext, parameters, fetchedValue);
493495
if (!executionContext.isNoOpDataLoaderDispatch()) {
494496
executionContext.getDataLoaderDispatcherStrategy().stopComplete(parameters);
495497
}
@@ -503,7 +505,7 @@ protected Object resolveFieldWithInfo(ExecutionContext executionContext, Executi
503505
return result;
504506
} else {
505507
try {
506-
FieldValueInfo fieldValueInfo = completeField(fieldDef, executionContext, parameters, fetchedValueObj);
508+
FieldValueInfo fieldValueInfo = completeField(fieldDef, parentType, executionContext, parameters, fetchedValueObj);
507509
if (fieldCtx != null) {
508510
fieldCtx.onDispatched();
509511
fieldCtx.onCompleted(FetchedValue.getFetchedValue(fetchedValueObj), null);
@@ -791,11 +793,10 @@ protected FieldValueInfo completeField(ExecutionContext executionContext,
791793
Field field = parameters.getField().getSingleField();
792794
GraphQLObjectType parentType = parameters.getExecutionStepInfo().getUnwrappedNonNullTypeAs();
793795
GraphQLFieldDefinition fieldDef = getFieldDef(executionContext.getGraphQLSchema(), parentType, field);
794-
return completeField(fieldDef, executionContext, parameters, fetchedValue);
796+
return completeField(fieldDef, parentType, executionContext, parameters, fetchedValue);
795797
}
796798

797-
private FieldValueInfo completeField(GraphQLFieldDefinition fieldDef, ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object fetchedValue) {
798-
GraphQLObjectType parentType = parameters.getExecutionStepInfo().getUnwrappedNonNullTypeAs();
799+
private FieldValueInfo completeField(GraphQLFieldDefinition fieldDef, GraphQLObjectType parentType, ExecutionContext executionContext, ExecutionStrategyParameters parameters, Object fetchedValue) {
799800
ExecutionStepInfo executionStepInfo = createExecutionStepInfo(executionContext, parameters, fieldDef, parentType);
800801

801802
boolean noOpFieldInstr = executionContext.isNoOpFieldInstrumentation();
@@ -966,22 +967,29 @@ protected FieldValueInfo completeValueForList(ExecutionContext executionContext,
966967
}
967968

968969
List<FieldValueInfo> fieldValueInfos = new ArrayList<>(size.orElse(1));
970+
// Hoist loop-invariant computations: the parent path and local context don't change per element,
971+
// and the list element type (unwrapped from the list type) is the same for all elements
972+
ResultPath parentPath = parameters.getPath();
973+
Object parentLocalContext = parameters.getLocalContext();
974+
GraphQLList listFieldType = executionStepInfo.getUnwrappedNonNullTypeAs();
975+
GraphQLOutputType typeInList = (GraphQLOutputType) listFieldType.getWrappedType();
969976
int index = 0;
970977
for (Object item : iterableValues) {
971978
if (incrementAndCheckMaxNodesExceeded(executionContext)) {
972979
return new FieldValueInfo(NULL, null, fieldValueInfos);
973980
}
974981

975-
ResultPath indexedPath = parameters.getPath().segment(index);
982+
ResultPath indexedPath = parentPath.segment(index);
976983

977-
ExecutionStepInfo stepInfoForListElement = executionStepInfoFactory.newExecutionStepInfoForListElement(executionStepInfo, indexedPath);
984+
// Inline newExecutionStepInfoForListElement to avoid per-element getUnwrappedNonNullTypeAs + getWrappedType
985+
ExecutionStepInfo stepInfoForListElement = executionStepInfo.transform(typeInList, executionStepInfo, indexedPath);
978986

979987
Object fetchedValue = unboxPossibleDataFetcherResult(executionContext, parameters, item);
980988

981989
ExecutionStrategyParameters newParameters = parameters.transform(
982990
stepInfoForListElement,
983991
indexedPath,
984-
FetchedValue.getLocalContext(fetchedValue, parameters.getLocalContext()),
992+
FetchedValue.getLocalContext(fetchedValue, parentLocalContext),
985993
FetchedValue.getFetchedValue(fetchedValue)
986994
);
987995

0 commit comments

Comments
 (0)