diff options
author | Itamar Ostricher <itamarost@gmail.com> | 2023-05-06 15:15:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-06 15:15:27 (GMT) |
commit | 263abd333d18b8825cf6d68a5051818826dbffce (patch) | |
tree | 9f6eaf466c5bc568ba3d85ba27532c1acc50a3e8 | |
parent | 96f95df48e41ccf984de1ee1312c81809fd9e876 (diff) | |
download | cpython-263abd333d18b8825cf6d68a5051818826dbffce.zip cpython-263abd333d18b8825cf6d68a5051818826dbffce.tar.gz cpython-263abd333d18b8825cf6d68a5051818826dbffce.tar.bz2 |
gh-104144: Optimize gather to finish eagerly when all futures complete eagerly (#104138)
-rw-r--r-- | Lib/asyncio/tasks.py | 13 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2023-05-03-16-50-24.gh-issue-104144.yNkjL8.rst | 3 |
2 files changed, 15 insertions, 1 deletions
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index aa5269a..7eb647b 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -813,6 +813,7 @@ def gather(*coros_or_futures, return_exceptions=False): children = [] nfuts = 0 nfinished = 0 + done_futs = [] loop = None outer = None # bpo-46672 for arg in coros_or_futures: @@ -829,7 +830,10 @@ def gather(*coros_or_futures, return_exceptions=False): nfuts += 1 arg_to_fut[arg] = fut - fut.add_done_callback(_done_callback) + if fut.done(): + done_futs.append(fut) + else: + fut.add_done_callback(_done_callback) else: # There's a duplicate Future object in coros_or_futures. @@ -838,6 +842,13 @@ def gather(*coros_or_futures, return_exceptions=False): children.append(fut) outer = _GatheringFuture(children, loop=loop) + # Run done callbacks after GatheringFuture created so any post-processing + # can be performed at this point + # optimization: in the special case that *all* futures finished eagerly, + # this will effectively complete the gather eagerly, with the last + # callback setting the result (or exception) on outer before returning it + for fut in done_futs: + _done_callback(fut) return outer diff --git a/Misc/NEWS.d/next/Library/2023-05-03-16-50-24.gh-issue-104144.yNkjL8.rst b/Misc/NEWS.d/next/Library/2023-05-03-16-50-24.gh-issue-104144.yNkjL8.rst new file mode 100644 index 0000000..b975d48 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-05-03-16-50-24.gh-issue-104144.yNkjL8.rst @@ -0,0 +1,3 @@ +Optimize :func:`asyncio.gather` when using :func:`asyncio.eager_task_factory` +to complete eagerly if all fututres completed eagerly. +Avoid scheduling done callbacks for futures that complete eagerly. |