I need to run 20 tasks asynchronously (each task runs the same function, but with a different argument). Each task uses Python's yfinance API module. This is my current method:
- Define a list
argswith 20 elements; each element is the argument to be passed to the corresponding task. - Define an async function
get_datawhich I will run 20 times with a different argument each time. - Define an async function
mainwhich will useasyncio.gatherto run the 20 tasks asynchronously.
And here is the (pseudo)code:
import asyncio
stocks = []
args = ['arg1', 'arg2', ... , 'arg20']
async def get_data(arg):
stock = Stock(arg)
# do some yfinance calls
return stock
async def main():
global stocks
tasks = [asyncio.ensure_future(get_data(arg)) for arg in args]
stocks = await asyncio.gather(*tasks)
asyncio.run(main())
print(stocks) # should be a list of 20 return values from the 20 tasks
Assume each task on its own takes 4 seconds to run. Then the 20 tasks should run in 4 seconds if it's running asynchronously. However, it is running in 80 seconds. If I remove all the async code and just run it synchronously, it runs in the same amount of time. Any help?
Thanks.
get_data()function is not awaiting anything, which is a red flag that it's async in name only, but in fact is blocking. To get benefits of asyncio, you need to use an async library for accessing stocks (or whatever else the code needs), and useawait.