Closed adriangb closed 2 years ago
Interesting. Is this approach more efficient? I find the added clarity of the method being async better if not.
Is this approach more efficient?
In theory, yes. Here's a quick benchmark:
import asyncio
import timeit
from typing import Awaitable, Callable
async def user_func() -> None:
return None
def def_func() -> Awaitable[None]:
return user_func()
async def async_def_func() -> None:
return await user_func()
async def test(func: Callable[[], Awaitable[None]]) -> float:
start = timeit.default_timer()
for _ in range(100_000):
await func()
return (timeit.default_timer() - start) / 100_000
print(asyncio.run(test(def_func))) # 2e-7
print(asyncio.run(test(async_def_func))) # 3e-7
I find the added clarity of the method being async better if not.
I agree. And I'm realizing this is a public facing function, so it would be reasonable to keep it as is just for that (if so, please just close this PR). On the other hand, because of the annotations, user's IDEs should treat the two as equivalent. It's only if a user looks at the source that they might be confused.
Nonetheless, I think it's an interesting tidbit to keep in mind.
since there are no awaits in this function other than the return, you can just return the await able objet directly and let the caller await that