Skip to content

perf(execution): reduce field overhead - faster introspection - #299

Merged
Cito merged 1 commit into
graphql-python:mainfrom
dexhunter:perf/field-arguments
Nov 5, 2026
Merged

Cito merged 1 commit into
graphql-python:mainfrom
dexhunter:perf/field-arguments

Conversation

@dexhunter

Copy link
Copy Markdown
Contributor

TL;DR

  • Reduce execute_field overhead during synchronous query execution.
  • Skip empty argument processing and pass async error-handler state as parameters.
  • Large-schema introspection benchmark median: 256.18 ms → 246.13 ms, 3.9% less time.
  • PYTHONPATH=src python -m pytest tests -q: 3,613 passed, 18 skipped.

Refs #298

What & Why

Each field currently calls argument coercion, even when the field and query have no arguments.
An inner async function also captures local values, which adds work to synchronous calls.

Use an empty dictionary directly when both argument collections are empty.
Give the async function explicit parameters so ordinary field execution does not need those captured values.

Results

Situation Before After Change
GitHub schema introspection 256.18 ms 246.13 ms 3.9% less time
Async list with 1,000 items 1.191 ms 1.201 ms Within variation: 0.9% more time
Large query pickle decoding 6.938 ms 7.165 ms Within variation: 3.3% more time

These are median times from at least 50 rounds on CPython 3.12.13, Linux x86-64, and an AMD EPYC 9R14.
Both versions ran sequentially on the same CPU.
The async-list and pickle-decoding slowdowns are smaller than the larger interquartile spread from their respective runs.
The async benchmark resolves one field and spends most of its time processing list items.
Pickle decoding does not call the changed method.

Validation

Run on the base commit and this change:

PYTHONPATH=src python -m pytest tests/benchmarks/test_introspection_from_schema.py tests/benchmarks/test_async_iterable.py tests/benchmarks/test_serialization.py::test_pickle_large_query_decode --benchmark-enable --benchmark-min-rounds=50
python -m ruff check src tests
python -m ruff format --check src tests
python -m mypy src tests

Ruff, formatting, and mypy passed for all 355 source and test files.

Why this is safe and easy to maintain

The patch changes one method and adds no helpers or dependencies.
Resolver arguments, completion, returned values, and error handling stay unchanged.
Existing execution tests cover resolver information, subclass hooks, middleware, argument defaults, and nullable errors.

Scope

This changes Python execution overhead without adding features or changing public signatures.
It keeps the existing GraphQL execution rules and resolver-information constructor.

AI assistance

Codex gpt-6.1-sol generated candidates tracked with Weco Observe.
Codex also helped run automated checks and prepare this description.

Weco share link: https://dashboard.weco.ai/share/NKlrkTVvI9HA-J73ZOdnjmMXw0g4xOYq

Skip coercion when the field and query node have no arguments.
Pass async error-handler state as parameters to avoid closure cells
in ordinary field execution.

Co-Authored-By: Aiden <aiden@weco.ai>
@dexhunter
dexhunter requested a review from Cito as a code owner November 5, 2026 12:46
@codspeed

codspeed Bot commented Nov 5, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 18.7%

1 warning

⚠️ 1 benchmark with a significant change ran in a different software environment

Its base and head results were measured with a different OS or toolchain, such as compiler, runtime or library versions, so the change might come from this difference rather than from the code. Open the benchmark to see what changed.

See affected benchmarks

⚡ 1 improved benchmark
✅ 19 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
⚡ test_execute_introspection_query 2.3 s 1.9 s +18.7%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing dexhunter:perf/field-arguments (fd1d4a9) with main (f9bdf7c)

Open in CodSpeed

@Cito
Cito merged commit 3b20727 into graphql-python:main Nov 5, 2026
11 checks passed
Cito pushed a commit that referenced this pull request Nov 5, 2026

@Cito Cito left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Results match main for queries with and without arguments, including async errors, and with this and #297 applied, introspection execution takes about 13% less time. This will be part of 3.3.2.

@Cito Cito changed the title perf(execution): reduce field overhead -- introspection 3.9% less time perf(execution): reduce field overhead - faster introspection Nov 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants