PHP JSON性能变慢主因是json_decode需全文扫描验证语法,时间复杂度O(N),大体积数据加剧内存占用与CPU压力,且默认配置未适配中文、深度、精度等实际需求。

json_decode 需要全文扫描才能确认结构
它不像 serialize/unserialize 那样在序列化时就写入类型与长度信息。json_decode 必须逐字符读到末尾(EOF),反复验证括号匹配、引号闭合、逗号分隔等语法,才能安全构建 PHP 数据结构。字符串越长,扫描次数越多——理论时间复杂度接近 O(N),N 是 JSON 字符总数。
这意味着:
- 一个 2MB 的 JSON 字符串,哪怕只取其中 10 个字段,
json_decode仍要完整读完全部内容 - 高并发下大量短 JSON 请求叠加,CPU 在字符遍历上持续打转,响应毛刺明显
- 中文多的 JSON 更吃力:UTF-8 多字节编码导致指针移动和边界判断更复杂
大体积数据一次性加载压爆内存
常见写法:$data = json_decode(file_get_contents('big.json'), true)。这会让 PHP 进程同时持有原始字符串 + 解析后数组两份副本。实测 50MB JSON 可能占用 150MB+ 内存,触发 GC 频繁或直接 OOM。
尤其在 CLI 或常驻进程(如 Swoole)中,内存不释放会持续累积,后续请求即使处理小数据也卡顿。
立即学习“PHP免费学习笔记(深入)”;
默认配置没适配实际需求
几个容易被忽略但影响显著的点:
-
中文被转成 \uXXXX:没加
JSON_UNESCAPED_UNICODE,编码/解码多一层转换,还增大字符串体积 -
深度限制拖慢失败路径:嵌套超 512 层时,解析器走到末尾才发现失败,白跑一趟;错误检测又额外调用
json_last_error() -
浮点数精度干扰:
serialize_precision设置过低(如 -1),会导致数字被截断再重编码,引发隐式类型转换开销
替代方案不是“换函数”,而是选对策略
不用 JSON 并不总是可行,但可以优化使用方式:
- 小数据(json_encode/decode,加
JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR - 大数据(> 1MB)、只读部分字段 → 改用流式解析库(如
salsify/json-stream或jsonpath提取) - 内部服务间通信、强 PHP 生态 → 考虑
igbinary或msgpack,比 JSON 快 2–5 倍且体积更小 - 高频简单结构(如日志、埋点)→ 直接用
serialize/unserialize,尤其含大量中文时,实测快 8–10 倍



















