collect_fields spends extra time on selections without directives

Đang mở Phù hợp với người mới
#315 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@dexhunter đang làm issue này rồi.

Từ ngày 8/11/2026.

  • #316 của @dexhunter — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python
Lĩnh vực
performance

Hướng nghiên cứu

Bắt đầu với visit_selection_sets() trong src/graphql/execution/collect_fields.py và theo dõi lời gọi đến should_include_node() đối với các lựa chọn có và không có chỉ thị. Kiểm tra các bài kiểm thử hiện có về thu thập trường và hành vi của chỉ thị trước khi thay đổi vòng lặp. Tối ưu hóa được xem là hoàn tất khi vẫn giữ nguyên kết quả, lỗi và danh sách chỉ thị bị cấm, đồng thời tránh các lần kiểm tra chỉ thị không cần thiết; hãy so sánh thời gian với các trường hợp benchmark trong issue.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
Python
Star
534
Fork
159
Merge trung bình
1 ngày 18 giờ
Pull request đã merge (30 ngày)
9

Chuẩn bị môi trường

  • Không có Dockerfile hay tệp Docker Compose
  • Có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của graphql-python/graphql-core

Tất cả issue của graphql-python/graphql-core

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.