换用其他 JSON 库可使解码快 6–7 倍、内存分配减少 75%,但需正确使用且数据规模足够大;小对象提升不明显。

直接换掉 encoding/json,性能提升不是“百倍”,但解码快 6–7 倍、内存分配少 75% 是真实可测的——前提是用对方式,且数据规模够大。小对象(
替换 import 就能生效?得看这三处配置
仅把 import "encoding/json" 换成 import "github.com/json-iterator/go" 并不够。必须显式使用兼容配置,否则可能触发非冻结 config 导致反射缓存未启用,性能反而退化。
-
var json = jsoniter.ConfigCompatibleWithStandardLibrary—— 这是关键,它调用Froze()启用反射缓存和对象池 - 不要用裸
jsoniter.ConfigDefault,它默认不冻结,每次解析都重新生成编解码器 - 若需自定义(如
EscapeHTML: false),必须在Froze()前设置:jsoniter.Config{EscapeHTML: false}.Froze()
为什么大 JSON 解码快 4–6 倍?核心在迭代器复用
标准库每次 json.Unmarshal 都新建 Decoder 和底层 reflect.Value 缓存;jsoniter 的 Iterator 对象从 sync.Pool 复用,避免了高频分配。
- 流式场景下,手动复用
jsoniter.Iterator实例比反复调用jsoniter.Unmarshal更省:先iter.Reset(bytes),再iter.ReadXXX() - 嵌套结构越深、字段越多,反射缓存收益越明显;单层 map[string]string 提升有限
- 注意:
Iterator不是 goroutine 安全的,每个 goroutine 应持有独立实例或从 pool 获取
浮点数/整数解析快 2–5 倍?靠的是跳过字符串转换
标准库解析数字时,先读完整字符串,再调用 strconv.ParseFloat;jsoniter 在 iter_float.go 中用状态机边读边算,整数部分用位运算(value 替代 <code>value * 10),小数部分按位权累加。
- 对
"123.45"这类常见格式走快速路径;"1.234567890123456789e+100"则 fallback 到strconv - 如果你的 JSON 里大量出现科学计数法或超长小数,实测加速会打折扣
- 无需改业务逻辑,但要注意:快速路径下
NaN/Infinity默认被拒绝(可配AllowInvalidNumber: true)
真正拉开差距的不是 API 替换动作本身,而是是否让反射缓存生效、是否复用迭代器、以及数据特征是否匹配它的快速路径。压测时务必用真实业务 JSON 样本,别只跑空结构体 benchmark。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











