Make is_awaitable faster for values that are not awaitable

Đang mở Phù hợp với người mới
#308 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 7/11/2026.

  • #309 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
72/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python

Hướng nghiên cứu

Bắt đầu bằng cách tìm is_awaitable trong mã nguồn graphql-core, rồi đọc các nơi gọi hàm này và những bài kiểm thử hiện có cho coroutine, coroutine dựa trên generator, future và các đối tượng cung cấp __await__. Tái tạo benchmark bằng tests/benchmarks/test_async_iterable.py với lệnh trong issue, sau đó so sánh hành vi và thời gian chạy sau khi thay đổi thứ tự kiểm tra như đề xuất. Hoàn thành khi vẫn giữ được các kết quả awaitable và lỗi đã liệt kê, đồng thời cải thiện trường hợp không phải awaitable.

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

Mô tả

is_awaitable runs up to three checks for every value.
For a plain value such as an int or a str, it always runs all three.
The executor calls it for every resolved and completed item, so a list of 1,000 items runs it about 2,000 times.

The CoroutineType test does not change the result.
Every coroutine object has an __await__ attribute, so the hasattr check also finds it.
Generator-based coroutines (types.coroutine) have no __await__, so they still need the code-flag check.

A local change removes the CoroutineType test.
It checks the exact generator type first and then checks for __await__.

Situation Before After Change
test_execute_async_iterable_list_field (median) 1.183 ms 1.115 ms 5.8% less time
Sync list field with 1,000 items 1.019 ms 0.927 ms 9.0% less time
1,000 async field resolvers (coroutines) 7.75 ms 7.83 ms Within variation: 1.0% more time
is_awaitable(1) 102.9 ns 66.0 ns 35.9% less time
is_awaitable(coroutine) 54.0 ns 87.8 ns 62.6% more time

The coroutine call itself is slower, because hasattr costs more than isinstance.
In a full query this cost stays inside normal variation, because awaiting the coroutine costs much more.

The results are the same for coroutines, generator-based coroutines, futures, and objects with __await__ on the instance, via __getattr__, or via a property.
Errors from a raising __getattr__ or property stay the same.

Environment: CPython 3.12.13, Linux x86-64, one dedicated CPU core.
Base commit: 1d505c19bf5fb8da0205165b78af6094d637009e.

Reproduce on the base and changed versions:

PYTHONPATH=src python -m pytest tests/benchmarks/test_async_iterable.py --benchmark-enable --benchmark-min-rounds=1000
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.