Python asyncio搭配httpx实现异步请求耗时与同步相近,是哪里出错了?
问题核心原因
- 异步调用逻辑错误,没有实现并发执行:
asyncio.run()会启动一个全新的事件循环并阻塞等待传入的协程执行完成才返回,你在for循环中逐个调用asyncio.run(async_pull(url)),相当于每次只发一个请求、等请求返回后才发下一个,本质上还是串行执行,和同步执行逻辑完全一致,自然耗时差异极小。 - 存在额外性能损耗:每次执行
async_pull都新建一个httpx.AsyncClient实例,没有复用连接池,反而带来了额外的连接建立开销。
修正后可实现异步并发的代码
import httpx import asyncio import time async def async_pull(client: httpx.AsyncClient, url: str): r = await client.get(url) print(r.status_code) async def async_main(): goog_fin_nyse_url = 'https://www.google.com/finance/quote/' tickers = ['F', 'TWTR', 'CVX', 'VZ', 'GME', 'GM', 'PG', 'AAL', 'MARK', 'AAP', 'THO', 'NGD', 'ZSAN', 'SEAC'] # 复用同一个AsyncClient,享受连接池优化 async with httpx.AsyncClient() as client: # 生成所有请求的协程对象 tasks = [async_pull(client, f"{goog_fin_nyse_url}{ticker}:NYSE") for ticker in tickers] # 批量并发执行所有协程 await asyncio.gather(*tasks) if __name__ == "__main__": def sync_pull(url): r = httpx.get(url) print(r.status_code) goog_fin_nyse_url = 'https://www.google.com/finance/quote/' tickers = ['F', 'TWTR', 'CVX', 'VZ', 'GME', 'GM', 'PG', 'AAL', 'MARK', 'AAP', 'THO', 'NGD', 'ZSAN', 'SEAC'] print("Running asynchronously...") async_start = time.time() # 仅调用一次asyncio.run,一次性执行所有并发任务 asyncio.run(async_main()) async_end = time.time() print(f"Time lapsed is: {async_end - async_start}") print("Running synchronously...") sync_start = time.time() for ticker in tickers: url = goog_fin_nyse_url + ticker + ':NYSE' sync_pull(url) sync_end = time.time() print(f"Time lapsed is: {sync_end - sync_start}")
优化效果说明
修改后的异步代码会同时发起所有请求,整体耗时接近单个请求的耗时,远低于串行执行的同步请求耗时。
内容的提问来源于stack exchange,提问作者Ubaidul Khan
相关产品推荐
相关产品推荐

