为何使用asyncio.gather与直接await任务的执行时间存在差异?
问题:两段Python异步代码功能一致,为何执行时间差异明显?
代码示例
import asyncio import time ... # Block 1: start_time = time.time() tasks = [ get_from_knowledge_v2(...), get_from_knowledge_v2(...), get_from_knowledge_v2(...), ] data_list = await asyncio.gather(*tasks) print("TIME TAKEN::", time.time() - start_time) # Block 2: start_time = time.time() data1 = await get_from_knowledge_v2(...) data2 = await get_from_knowledge_v2(...) data3 = await get_from_knowledge_v2(...) print("WITHOUT ASYNCIO GATHER TIME TAKEN::", time.time() - start_time)
执行结果
TIME TAKEN:: 0.6016566753387451 WITHOUT ASYNCIO GATHER TIME TAKEN:: 1.7620849609375
原因分析
这两段代码的核心差异在于任务的执行方式:
- Block 1(asyncio.gather):三个
get_from_knowledge_v2协程被同时提交给事件循环,属于并发执行。当其中一个协程遇到IO等待(比如网络请求、数据库查询这类耗时但不占用CPU的操作)时,事件循环会切换到另一个已就绪的协程继续执行。三个任务的等待时间是重叠的,总耗时接近单个任务的最长执行时间,所以最终只用了约0.6秒。 - Block 2(串行await):每一个
await都会阻塞当前流程,必须等前一个协程完全执行完毕,才会启动下一个。三个任务的执行时间是累加的,总耗时约为单个任务耗时的3倍(0.6*3≈1.8,和实际的1.76秒吻合)。
简单来说,asyncio.gather的作用就是让多个异步任务并发运行,充分利用IO等待的间隙,大幅缩短整体执行时间;而串行await则是按顺序逐个执行任务,时间自然是累加的。
内容的提问来源于stack exchange,提问作者Shashank Srivastava
相关产品推荐
相关产品推荐

