You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CPython just applied an optimization to asyncio which avoids creating a full-fledged Task object if possible: python/cpython#97696. This apparently gives up to a 50% speedup on some asyncio benchmarks.
In principle, the same optimization should apply to asynq: we always create an AsynqTask and put it on the scheduler for every executed asynq function, but many asynq function likely complete without ever needing to block. I don't have hard numbers for that, though.
This optimization could be implemented mostly in _call_pure (
If self.needs_wrapper is true, we have an @asynq function that never yields. We can just return a ConstFuture directly without going through the scheduler.
Otherwise, we do need to execute the generator. We can start the first step of the generator. If it returns, we can end early too and return a ConstFuture. If it yields, we can check whether it's yielding a ConstFuture: if so, we can simply send the ConstFuture back into the generator and proceed. But if it yields something else, we have to fall back to using the real scheduler.
This change could break user-visible behavior in some ways: for example, there is code in the @deduplicate decorator that assumes .asynq() always returns an AsyncTask, not a ConstFuture. Adapting such code may need some additional work. Compare python/cpython#97696 (comment).
The text was updated successfully, but these errors were encountered:
CPython just applied an optimization to asyncio which avoids creating a full-fledged Task object if possible: python/cpython#97696. This apparently gives up to a 50% speedup on some asyncio benchmarks.
In principle, the same optimization should apply to asynq: we always create an AsynqTask and put it on the scheduler for every executed asynq function, but many asynq function likely complete without ever needing to block. I don't have hard numbers for that, though.
This optimization could be implemented mostly in
_call_pure
(asynq/asynq/decorators.py
Line 130 in c5dc852
self.needs_wrapper
is true, we have an@asynq
function that never yields. We can just return a ConstFuture directly without going through the scheduler.This change could break user-visible behavior in some ways: for example, there is code in the
@deduplicate
decorator that assumes.asynq()
always returns anAsyncTask
, not aConstFuture
. Adapting such code may need some additional work. Compare python/cpython#97696 (comment).The text was updated successfully, but these errors were encountered: