Open bdraco opened 1 month ago
call_at benchmark with the change in #122882
import asyncio
import timeit
def run():
asyncio.run(call_at())
async def call_at():
loop = asyncio.get_running_loop()
when = loop.time()
future = loop.create_future()
def callback():
"""Callback function."""
def done():
"""Done function."""
future.set_result(None)
for _ in range(100):
when += 0.00000001
loop.call_at(when, callback)
loop.call_at(when, done)
await future
print("call_at_benchmark", timeit.timeit(run))
before: call_at_benchmark 252.9052056250075
after: call_at_benchmark 228.09943808300886
Wow, this was an excellent problem analysis.
Your recommended solution seems reasonable to me.
Feature or enhancement
Proposal:
The
heapq
calls in base_events.py represents quite a bit of asyncio scheduling overhead because they have to run__lt__
quite often inTimerHandle
https://github.com/python/cpython/blob/0fd97e46c75bb3060485b796ca597b13af7e6bec/Lib/asyncio/events.py#L128https://github.com/python/cpython/blob/0fd97e46c75bb3060485b796ca597b13af7e6bec/Lib/asyncio/base_events.py#L1968
https://github.com/python/cpython/blob/0fd97e46c75bb3060485b796ca597b13af7e6bec/Lib/asyncio/base_events.py#L815
https://github.com/python/cpython/blob/0fd97e46c75bb3060485b796ca597b13af7e6bec/Lib/asyncio/base_events.py#L1975
Avoiding running
__lt__
can speed up processingcall_at
s by ~10%Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
Wrapping
TimerHandle
in a tuple starting withwhen
avoids the__lt__
call. Thank you to whoever wrote theheapq
docs for help getting there https://docs.python.org/3/library/heapq.html#basic-examples 6f80b4c8b7beExample benchmark
Linked PRs