Make is_awaitable faster for values that are not awaitable
Les mainteneurs répondent en général sous 1 jour
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 72/100
- Type d'issue
- Bug
- Clarté
- Plutôt claire
- Activité
- Active
- Stack technique
- python
- Domaine
- backend-api-design, performance
Piste de recherche
Commencez par localiser is_awaitable dans le code source de graphql-core et lisez ses appelants ainsi que les tests existants pour les coroutines, les coroutines basées sur des générateurs, les futures et les objets exposant __await__. Reproduisez le benchmark avec tests/benchmarks/test_async_iterable.py à l’aide de la commande indiquée dans l’issue, puis comparez le comportement et le temps d’exécution après la modification proposée de l’ordre des vérifications. Le travail est terminé si les résultats et les erreurs awaitable répertoriés sont préservés, tout en améliorant le cas non-awaitable.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
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
- Langage dominant
- Python
- Étoiles
- 534
- Forks
- 159
- Merge moyen
- 1 j 18 h
- PR mergées (30 j)
- 9
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Aucun guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de graphql-python/graphql-core
-
collect_fields spends extra time on selections without directivesPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
graphql-python/graphql-core#315 ·
Les mainteneurs répondent en général sous 1 jour
-
is_printable_as_block_string checks each character in a Python loopPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 83/100
graphql-python/graphql-core#312 ·
Les mainteneurs répondent en général sous 1 jour
-
natural_comparison_key: faster sort keys for names without digitsPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
graphql-python/graphql-core#310 ·
Les mainteneurs répondent en général sous 1 jour
-
assert_name checks each character in a Python generatorPeut-être pris @swayamdudhela l’a pris il y a 2 jours. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
graphql-python/graphql-core#304 · 4 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
coerce_input_literal spends extra time on type checks and non-null recursionPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
graphql-python/graphql-core#302 ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de graphql-python/graphql-core
Issues similaires
-
`destroy` sans terminal répond « Aborted. » au lieu de réclamer `--yes` comme `clean` et `reset`Ouvertebug
Difficulté 2/5 1-3 heures Accessibilité débutants 85/100
stephrobert/dsoxlab#354 ·
Les mainteneurs répondent en général sous 1 jour
-
hardware help wanted testing
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 77/100
jasonacox/pypowerwall#472 ·
Les mainteneurs répondent en général sous 1 jour
-
[Bug]: DoubleMLRDDData accepts a score_col that is no data column (as in its docstring example); the running variable then becomes a covariate and RDFlex failsPeut-être pris @vrjdev l’a pris aujourd’hui. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
DoubleML/doubleml-for-py#455 ·
Les mainteneurs répondent en général sous 1 jour
-
[Bug]: Python mod.Box[T] annotation gets a false generic_arg edge that replaces the parameter_type one ('is' on tree-sitter nodes)Peut-être pris @rohit-jsfreaky l’a pris aujourd’hui. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 88/100
Graphify-Labs/graphify#5110 · 1 commentaire ·
Les mainteneurs répondent en général sous 2 jours