uvloop可提升Python异步性能2–5倍,但需正确配置:Python 3.12+用uvloop.run()直接启动;旧版本须提前设置事件循环策略;仅优化I/O密集型任务,需同步启用连接池与DNS缓存。

uvloop 能让 Python 异步性能提升 2–5 倍,但“提升一倍以上”不是自动发生的——它取决于你是否绕过了常见配置陷阱、是否在合适场景启用、以及是否避免了隐式降级。
uvloop.run() 是最简启动方式,但只适用于 Python 3.12+
如果你用的是 Python 3.12 或更新版本,uvloop.run() 是首选:它直接接管整个事件循环生命周期,不经过 asyncio.run() 的兼容层,开销最小。
错误写法(仍走 asyncio 默认路径):
import asyncio import uvloop <p>async def main(): await asyncio.sleep(0.1)</p><h1>❌ 这样调用没用:asyncio.run() 会忽略 uvloop.install()</h1><p>asyncio.run(main())
正确写法:
立即学习“Python免费学习笔记(深入)”;
-
uvloop.run(main())—— 一行启动,无额外封装 - 不需手动
uvloop.install()或set_event_loop_policy() - 若项目依赖
asyncio.get_event_loop(),确保它只在uvloop.run()内部被调用(外部调用会触发 RuntimeError)
Python 3.11 及更早版本必须显式安装策略
在旧版本中,uvloop.install() 和 asyncio.set_event_loop_policy() 效果不同,且顺序敏感:
-
uvloop.install()是 legacy 方式,仅影响后续asyncio.run(),但不改变已存在的 loop 实例 -
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())才是推荐做法,它让所有新创建的 loop(包括asyncio.new_event_loop())都默认使用 uvloop - 必须在导入任何其他 asyncio 相关模块(如
aiohttp、asyncpg)之前执行,否则部分库可能已缓存了默认策略
典型失败场景:在 import aiohttp 后才调用 uvloop.install(),此时 aiohttp.TCPConnector 内部已创建过默认 loop,uvloop 不生效。
uvloop 不加速 CPU 密集型协程,反而可能暴露 GIL 问题
uvloop 只优化 I/O 调度,对纯计算任务无提速作用;更关键的是,它会让 CPU 密集型协程阻塞更明显——因为 uvloop 的事件循环更轻量、调度更快,没有 asyncio 默认 loop 那种“无意中插入的微小让步”。
例如以下代码在 uvloop 下会卡住整个事件循环:
async def cpu_bound():
# ❌ 危险:在协程里做密集计算
sum(i * i for i in range(10**7))
正确做法:
- 用
asyncio.to_thread()(Python 3.9+)把计算移到线程池 - 或用
uvloop/handles/process.pyx提供的子进程机制(需手动管理) - 绝对不要在
await链中混入长时间同步计算
连接池和 DNS 缓存必须手动开启,否则白换 uvloop
uvloop 自身不控制应用层连接复用。像 aiohttp、asyncpg 这类库,默认连接池大小保守(常为 10–100),DNS 解析也默认不缓存——这会让 uvloop 的高吞吐能力被上层拖垮。
关键配置项:
aiohttp.TCPConnector(limit=1000, limit_per_host=100, keepalive_timeout=30)-
asyncio.get_event_loop().set_dns_cache(True)(需在 uvloop 启动后立即调用) asyncpg.create_pool(..., min_size=20, max_size=200)
漏掉任一项,QPS 可能卡在原地,甚至因连接耗尽而报 ConnectionRefusedError 或超时。
uvloop 的加速效果高度依赖上下文:它本身极快,但只要有一处阻塞、一处未复用、一处策略加载顺序错误,整个链路就会回落到默认 asyncio 表现。真正起效的从来不是“用了 uvloop”,而是“所有环节都对齐了 uvloop 的运行假设”。



















