异步io不加速json解析,因json.loads()等是同步cpu密集型操作;真正异步的只有i/o;gb级json应使用ijson流式解析;仅当i/o完成且解析量大时才用run_in_executor。

异步IO本身不加速JSON解析,别被名字骗了
asyncio 不能让 json.loads() 或 orjson.loads() 变快——它们全是同步 CPU 密集型操作。事件循环会被阻塞,哪怕你用 await 包一层也没用。真正能异步的只有 I/O:比如从磁盘读文件、从网络接收响应体。解析动作必须和 I/O 拆开,否则“异步解析”只是假象。
大文件该用流式解析,不是 asyncio + loads
当你面对 GB 级单体 JSON(如一个超长数组或嵌套对象),json.load() 会直接 OOM。asyncio 对此无解。正确路径是用 ijson 做流式迭代:
-
ijson.parse()返回生成器,每次只吐出一个事件('start_map','string','number'),内存恒定在几 MB -
ijson.items(f, 'records.item')直接提取指定路径下的每个对象,适合日志/事件流结构 - 必须传
open(..., 'rb'),ijson内部按需读取字节块,不缓存全量 - 别在
async def里调ijson.items()后再await——它不返回协程,只是普通迭代器
什么时候才需要 loop.run_in_executor?
仅当你的工作流满足两个条件:I/O 已完成 + 解析量极大(例如每秒解析上千条 2–5KB 的 JSONL 行)。这时用线程池把 orjson.loads() 移出事件循环:
-
orjson.loads()要求输入是bytes,且必须是 UTF-8;传str会抛TypeError -
ujson.loads()对bytes支持不稳定,建议先data.decode('utf-8') - 单次解析
- 示例封装:
async def async_orjson_loads(data: bytes):<br> loop = asyncio.get_running_loop()<br> return await loop.run_in_executor(None, orjson.loads, data)
最容易被忽略的三件事
换库或加异步不是改个 import 就完事:
-
orjson.loads()默认返回键为bytes的字典(不是str!),后续用dict['key']会报KeyError -
ijson.items()提取的每个item是完整 Python 对象,但内部字段仍是原样类型(比如时间字符串不会自动转datetime) - 用
mmap+ujson看似能省内存,但ujson不支持部分内存映射区域,容易触发ValueError: Invalid JSON
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











