Skip to content

Index schema model lookups during code generation - #962

Merged
iuliiasobolevska merged 1 commit into
masterfrom
perf/schema-model-indexing
Sep 23, 2026
Merged

iuliiasobolevska merged 1 commit into
masterfrom
perf/schema-model-indexing

Conversation

@iuliiasobolevska

Copy link
Copy Markdown
Collaborator

Summary

Build a document-scoped schema index once and share it across code generation instead of repeatedly scanning the full GraphQL document.

The index preserves document order and the existing lookup semantics while covering:

  • type definitions by name
  • object, input, enum, interface, and union extensions by name
  • object implementations by interface
  • scalar Java type mappings

Existing public constructors and scan-based overloads remain available for source and binary compatibility. Internal generator paths use the shared index.

This also replaces the remaining interface implementation scan in client projection recursion and prevents duplicate subtype entries when an invalid schema repeats an interface, such as implements Node & Node.

Motivation

Large schemas perform many type and extension lookups during generation. Previously, each lookup walked all document definitions, so lookup work grew with both schema size and the number of generated fields and projections.

Index construction is linear in the document size, after which covered lookups are map-backed. This changes the covered work from repeated full-document scans toward one indexing pass plus lookup-result processing.

Expected performance impact

The adversarial review benchmark used a synthetic 1,200-type schema with extensions, mapped scalars, unions, interfaces, enums, inputs, and client projections. Median generation time improved by:

  • Java: 16,109 ms to 13,713 ms, approximately 14.9%
  • Kotlin: 16,497 ms to 13,789 ms, approximately 16.4%

Actual gains will vary with schema shape and enabled generators. This PR does not claim to eliminate every schema scan; residual per-field lookups in TypeUtils are intentionally left for a separate optimization.

Correctness safeguards

  • Preserve first-match and document-order behavior.
  • Preserve same-named scalar and non-scalar lookup behavior in either declaration order.
  • Preserve duplicate type definitions while deduplicating repeated interfaces within one object definition.
  • Compare indexed and scan implementations across all repository GraphQL schemas, all eight lookup flag combinations, scalar mappings, all five extension kinds, and field aggregation.
  • Retain the scan implementations as compatibility APIs and equivalence-test baselines.

Verification

  • ./gradlew :graphql-dgs-codegen-core:test :graphql-dgs-codegen-core:integTest --no-scan
  • ./gradlew :graphql-dgs-codegen-core:lintKotlinMain :graphql-dgs-codegen-core:lintKotlinTest --no-scan

@iuliiasobolevska
iuliiasobolevska merged commit cc11866 into master Sep 23, 2026
2 checks passed
@iuliiasobolevska
iuliiasobolevska deleted the perf/schema-model-indexing branch September 23, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants