From 5397cd9f62db0e695d94c59bafc119613110b672 Mon Sep 17 00:00:00 2001 From: Itamar Ostricher Date: Wed, 3 May 2023 11:08:44 -0700 Subject: [PATCH 1/4] gh-NNNN: Skip scheduling a done callback if a TaskGroup task completes eagerly --- Lib/asyncio/taskgroups.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 0fdea3697ece3d..81a19b66308258 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -163,9 +163,16 @@ def create_task(self, coro, *, name=None, context=None): task = self._loop.create_task(coro) else: task = self._loop.create_task(coro, context=context) - tasks._set_task_name(task, name) - task.add_done_callback(self._on_task_done) - self._tasks.add(task) + if name is not None: + tasks._set_task_name(task, name) + # optimization: Immediately call the done callback is the task is + # already done (e.g. if the coro was able to complete eagerly), + # and skip scheduling a done callback + if task.done(): + self._on_task_done(task) + else: + self._tasks.add(task) + task.add_done_callback(self._on_task_done) return task # Since Python 3.8 Tasks propagate all exceptions correctly, From 8d6a77e8c312bb1cbdaaca2f316897412fce4da3 Mon Sep 17 00:00:00 2001 From: Itamar Ostricher Date: Wed, 3 May 2023 16:52:01 -0700 Subject: [PATCH 2/4] Add NEWS entry --- .../next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst diff --git a/Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst b/Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst new file mode 100644 index 00000000000000..2daf7285cfaa42 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst @@ -0,0 +1,2 @@ +Optimize asyncio.TaskGroup when using eager tasks factory -- Skip scheduling +done callbacks when all tasks finish without blocking - for up to 4x speedup From a125c1fc495782429baca2f892b7a798ec9bdf4c Mon Sep 17 00:00:00 2001 From: Itamar Ostricher Date: Wed, 3 May 2023 17:53:50 -0700 Subject: [PATCH 3/4] Apply review feedback to NEWS entry Co-authored-by: Carl Meyer --- .../Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst b/Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst index 2daf7285cfaa42..59870de3e02edd 100644 --- a/Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst +++ b/Misc/NEWS.d/next/Library/2023-05-03-16-51-53.gh-issue-104144.653Q0P.rst @@ -1,2 +1 @@ -Optimize asyncio.TaskGroup when using eager tasks factory -- Skip scheduling -done callbacks when all tasks finish without blocking - for up to 4x speedup +Optimize :class:`asyncio.TaskGroup` when using :func:`asyncio.eager_task_factory`. Skip scheduling done callbacks when all tasks finish without blocking. From 161d0f8c6f0241bb20f887522659b1bc8700452d Mon Sep 17 00:00:00 2001 From: Itamar Ostricher Date: Fri, 5 May 2023 14:06:39 -0700 Subject: [PATCH 4/4] revert skipping _set_task_name if name is None; fix typo in comment --- Lib/asyncio/taskgroups.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 81a19b66308258..06b2e0db86a1fe 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -163,9 +163,8 @@ def create_task(self, coro, *, name=None, context=None): task = self._loop.create_task(coro) else: task = self._loop.create_task(coro, context=context) - if name is not None: - tasks._set_task_name(task, name) - # optimization: Immediately call the done callback is the task is + tasks._set_task_name(task, name) + # optimization: Immediately call the done callback if the task is # already done (e.g. if the coro was able to complete eagerly), # and skip scheduling a done callback if task.done():