collect_fields spends extra time on selections without directives

オープン 初心者向け
#315 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@dexhunter がすでに取り組んでいます。

2026年11月8日 から。

  • #316 @dexhunter による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
performance

調査の方向性

src/graphql/execution/collect_fields.py の visit_selection_sets() から始め、ディレクティブがある選択とない選択について、should_include_node() の呼び出しをたどります。ループを変更する前に、フィールド収集とディレクティブの動作に関する既存のテストを確認してください。この最適化では、結果、エラー、禁止ディレクティブのリストを維持しながら、不要なディレクティブチェックを避けられることが完了条件です。issue にあるベンチマークケースと実行時間を比較してください。

索引モデルが issue の本文から書いたものです。

説明

visit_selection_sets() in src/graphql/execution/collect_fields.py runs for every selection set before resolvers run.
For each selection, it calls should_include_node(), even when the selection has no directives.
should_include_node() then builds two generator expressions to look for @skip and @include.

Most fields in real queries have no directives, so this work is repeated for almost every field.

Situation Now With the proposed fix Change
collect_fields on 4,000 plain fields 4458.7 µs 4113.4 µs 7.7% less time
collect_fields on 4,000 fields with @include(if: $t) 10988.9 µs 8593.5 µs 21.8% less time
collect_fields on 40 inline fragments with 100 fields each 4561.1 µs 4165.7 µs 8.7% less time
collect_fields on 400 named fragment spreads with 1 field each 960.0 µs 889.9 µs 7.3% less time

These are medians of 31 timing rounds, and the median of 3 alternating processes per version.

Proposed fix: check selection.directives once in the loop and skip the should_include_node() call when it is empty.
Find @skip and @include in one plain loop instead of two generator expressions.
Results, errors and forbidden-directive lists stay the same.

Environment: CPython 3.12.13, Linux x86-64, AMD EPYC 9R14, graphql-core main at 1d505c1.

主要言語
Python
スター
534
フォーク
159
平均マージ
1日 18時間
マージ済み PR(30日)
9

環境構築

  • Dockerfile・Docker Compose ファイルなし
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

graphql-python/graphql-core のほかの issue

graphql-python/graphql-core の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。