为何使用asyncio.gather处理pandas DataFrame行数据时无法实现并发执行?
异步HTTP请求无法并发:aiohttp+asyncio性能与同步方案完全一致的问题
我最近在处理一个包含50万行数据的pandas DataFrame,每行都需要发起一次HTTP请求。为了获得显著的性能提升,我把原来基于requests的同步请求方案换成了aiohttp + asyncio的异步方案,但实际运行后发现,异步版本的执行速度居然和同步循环完全一样,完全没达到预期的并发效果。我实在找不到并发被阻塞的原因,下面是我的最小可复现示例代码:
import asyncio import aiohttp import pandas as pd import time # 包含100行数据的示例DataFrame,每行请求一个带延迟的端点 df = pd.DataFrame({ 'id': range(100), 'url': ['http://httpbin.org/delay/0.1'] * 100 }) async def fetch(session, url, row_id): async with session.get(url) as response: await response.text() return row_id async def process_dataframe(df): async with aiohttp.ClientSession() as session: tasks = [] for _, row in df.iterrows(): task = asyncio.create_task(fetch(session, row['url'], row['id'])) tasks.append(task) results = await asyncio.gather(*tasks) return results start = time.time() results = asyncio.run(process_dataframe(df)) print(f"Async time: {time.time() - start:.2f} seconds")
预期与实际结果
- 预期结果:向延迟0.1秒的端点发起100次请求,借助异步并发特性,应该能在0.1-0.2秒内完成
- 实际结果:脚本耗时约10秒,和同步循环的执行时间完全一致
已排查的内容
- 事件循环正常运行,未出现缺少事件环的
RuntimeError aiohttp已正确安装,运行过程中没有DNS/解析器阻塞相关的警告- 在macOS和Linux系统、Python 3.11与3.12版本下测试,均表现出相同的问题
我的疑问
为什么这些请求无法并发执行?是在异步函数中遍历DataFrame行数据的操作导致任务被序列化了,还是asyncio.create_task在紧凑循环中存在已知限制?
环境信息:Python 3.11.7、pandas 2.1.4、aiohttp 3.9.1
内容的提问来源于stack exchange,提问作者Джон Сноу
相关产品推荐
相关产品推荐

