Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Significant performance hit when using async resolvers

Aperta
#190 14 commenti 1 reazione 1 assegnatario Vedi su GitHub

@Cito ci sta già lavorando.

Dal 9/2/2023.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

investigate optimization

During development (Starlette + Ariadne) of our product I noticed significant performance degradation when GraphQL responses got significant long (1000+ entities in a list). I started profiling and drilling into the issue and I pinpointed it to async resolvers. Whenever a resolver is async and it is called a lot (100.000) you can see significant slowdowns 4x-7x, even if there is nothing async to it.

The question that I ended up with, is this a limitation of Python asyncio or how the results are gathered for async fields in graphql execute?

Any insight/help is greatly appreciated as we really need more performance and changing to sync is not really an option (nor is rewriting it to another language) 😭

import asyncio
from dataclasses import dataclass

from graphql import (
    GraphQLField,
    GraphQLList,
    GraphQLObjectType,
    GraphQLSchema,
    GraphQLString,
    graphql,
)

# On a MacBook Pro M1 Max this takes around 44 seconds in "async" case
# and "only" 7 seconds when async field is removed from the query
TOTAL_PEOPLE = 1000000


@dataclass
class Person:
    firstName: str
    lastName: str


def resolve_people(*_):
    return [Person(f"Jane{i}", "Do") for i in range(0, TOTAL_PEOPLE)]


def resolve_fullname(person: Person, *_):
    return f"{person.firstName} {person.lastName}"


async def async_resolve_fullname(person: Person, *_):
    return f"{person.firstName} {person.lastName}"


PersonType = GraphQLObjectType(
    "Person",
    {
        "firstName": GraphQLField(GraphQLString),
        "lastName": GraphQLField(GraphQLString),
        "fullName": GraphQLField(GraphQLString, resolve=resolve_fullname),
        "asyncFullName": GraphQLField(GraphQLString, resolve=async_resolve_fullname),
    },
)

schema = GraphQLSchema(
    query=GraphQLObjectType(
        name="RootQueryType",
        fields={
            "people": GraphQLField(GraphQLList(PersonType), resolve=resolve_people)
        },
    )
)


async def main():
    result = await graphql(
        schema,
        """#graphql
        query {
            people {
                firstName
                lastName
                fullName
                asyncFullName # THIS IS THE SLOW PART
            }
        }
    """,
    )
    assert len(result.data["people"]) == TOTAL_PEOPLE


def run(callable, is_profile: bool = False):
    if not is_profile:
        return asyncio.run(callable())

    import yappi

    yappi.set_clock_type("WALL")
    with yappi.run():
        asyncio.run(callable())

    func_stats = yappi.get_func_stats()

    func_stats.save("callgrind.func_stats", "callgrind")
    with open("func_stats.txt", "w") as file:
        func_stats.print_all(
            file,
            {
                # We increase the column widths significantly
                0: ("name", 120),
                1: ("ncall", 10),
                2: ("tsub", 12),
                3: ("ttot", 12),
                4: ("tavg", 12),
            },
        )


if __name__ == "__main__":
    run(main, is_profile=False)

image

Versions:

  • macOS: 13.2
  • python 3.11
  • graphql-core 3.2.3
  • yappi 1.4.0
Lingua principale
Python
Stelle
531
Fork
147
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di graphql-python/graphql-core

Tutte le issue di graphql-python/graphql-core

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.