我有一个IO操作(每个Pandas行的POST请求(,我正试图使用异步IO来加快速度。下面是另一个最小示例。我想了解为什么第一个样本没有并行运行,而第二个样本更快。
第一个样品:
from time import sleep
import asyncio
import nest_asyncio
nest_asyncio.apply()
async def add(x: int, y: int, delay: int):
sleep(delay) #await asyncio.sleep(delay)
return x+y
async def get_results():
inputs = [(2,3,9), (4,5,7), (6,7,5), (8,9,3)]
cors = [add(x,y,z) for x,y,z in inputs]
results = asyncio.gather(*cors)
print(await results)
asyncio.run(get_results())
# This takes ~24s
第二个样品:
from time import sleep
import asyncio
import nest_asyncio
nest_asyncio.apply()
async def add(x: int, y: int, delay: int):
await asyncio.sleep(delay)
return x+y
async def get_results():
inputs = [(2,3,9), (4,5,7), (6,7,5), (8,9,3)]
cors = [add(x,y,z) for x,y,z in inputs]
results = asyncio.gather(*cors)
print(await results)
asyncio.run(get_results())
# This takes ~9s as expected
在我的情况下,sleep
可以替换为requests.post()
requests
不支持异步,因此尝试在async
函数中使用它不会使速度更快。
您将需要一个异步感知的HTTP库,如httpx
或aiohttp
,以发出不阻塞async
函数的HTTP请求。
类似地,在第一个示例中,您使用了一个非异步感知函数time.sleep
,它阻塞异步循环。
此外,asyncio
不会加快非IO、Python本机代码操作(添加(的速度。
(回想一下,async
并不意味着这些函数将并行运行,恰恰相反。(
因为time.sleep
不是异步的。当运行到代码time.sleep
时,线程将被阻塞并等待。
但是await asyncio.sleep
是异步的。线程在运行到代码await asyncio.sleep
时可以自由执行其他代码。
sync
就像你必须点一份食物并等待它完成一样。然后你可以点下一份食物。
async
意味着您可以在一段时间内点完所有食物,并等待它们完成。
一旦代码进入sleep.delay,它将阻止所有其他协同例程在事件循环中执行。所有功能都必须是异步兼容的