-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-104144: Skip scheduling a done callback if a TaskGroup task completes eagerly #104140
Conversation
Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst
Outdated
Show resolved
Hide resolved
Co-authored-by: Carl Meyer <carl@oddbird.net>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
How sure are you that skipping the set-name call if name is None is always correct? (It seems fine to me, but in theory some 3rd party task implementation could do other stuff there.)
I don't know about all possible 3p task implementations. At least looking at uvloop, it seems it uses asyncio.Task directly. |
I don't think it will be measurable -- it looks to be a very minor part of creating a task (even more so with gh-103767). It just is one more thing we'd have to put in what's new (and it's not covered by the PR title :-). |
agreed, let me revert that part! |
@@ -0,0 +1 @@ | |||
Optimize :class:`asyncio.TaskGroup` when using :func:`asyncio.eager_task_factory`. Skip scheduling done callbacks when all tasks finish without blocking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm actually the scheduling is skipped on a per task basis rather than when all tasks finish without blocking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a fix in itamaro@ac1ee82 (PR depends on gh-104251 first)
…completes eagerly (python#104140) Co-authored-by: Carl Meyer <carl@oddbird.net>
gh-97696 introduced eager tasks factory, which speeds up some async-heavy workloads by up to 50% when opted in.
installing the eager tasks factory applies out-of-the-box when creating tasks as part of a
TaskGroup
, e.g.:coro{1,2,3}
will eagerly execute the first step, and potentially complete without scheduling to the event loop if the coros don't block.the implementation of
TaskGroup
uses callbacks internally that end up getting scheduled to the event loop even if all the tasks were able to finish synchronously, and blocking the coroutine in whichTaskGroup()
was awaited, preventing the task from completing eagerly even if otherwise it could.applications that use multiple levels of nested TaskGroups can benefit significantly from eagerly completing multiple levels without blocking, as implemented in this PR by skipping scheduling the done callback if the future is done.
Benchmarks
this makes the async pyperformance benchmarks up to 4x faster (!!), using a patch to pyperformance that adds "eager" flavors and uses TaskGroups instead of gather