golang,go,博客,开源,编程
一、库背景与核心优势
json-iterator/go(简称 jsoniter
)是滴滴开源的高性能JSON解析库,专为Go语言设计,完全兼容标准库 encoding/json
。其核心优势在于通过多项底层优化实现2-10倍的性能提升,尤其在反序列化场景下表现突出。以下是其技术亮点:
{"id":1}
时,直接计算 "id"
的哈希值定位目标字段。sync.Pool
复用 Stream
和 Iterator
对象,减少GC压力。实测单次反序列化内存分配次数从标准库的57,624次降至39次。场景 | 标准库耗时 | jsoniter耗时 | 提升倍数 |
---|---|---|---|
复杂结构反序列化 | 156,737ns | 18,733ns | 8.4x |
中等JSON解析 | 22429ns | 1300ns | 17.2x |
小对象序列化 | 8562ns | 1451ns | 5.9x |
(数据来源:)
*((*int)(ptr)) = iter.ReadInt()
。通过 jsoniter.Config
实现细粒度控制:
api := jsoniter.Config{
EscapeHTML: true, // 转义HTML标签
SortMapKeys: true, // 序列化Map时按键排序
MarshalFloatWith6Digits: true, // 浮点数保留6位小数
}.Froze() // 生成独立配置实例
支持PHP兼容模式(自动转换数字/字符串)、空数组转对象等特殊场景。
自定义编解码逻辑示例:
type PhoneExtension struct {
jsoniter.DummyExtension
}
func (e *PhoneExtension) DecorateDecoder(typ reflect.Type, decoder jsoniter.ValDecoder) jsoniter.ValDecoder {
if typ == reflect.TypeOf("") {
return &PhoneMaskDecoder{decoder}
}
return decoder
}
type PhoneMaskDecoder struct{ jsoniter.ValDecoder }
func (d *PhoneMaskDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
d.ValDecoder.Decode(ptr, iter)
phone := *(*string)(ptr)
*(*string)(ptr) = strings.Replace(phone, phone[3:7], "****", 1) // 手机号脱敏
}
无需定义结构体即可提取嵌套字段:
val := []byte(`{"user":{"contacts":[{"type":"mobile","number":"138****1234"}]}}`)
phone := jsoniter.Get(val, "user", "contacts", 0, "number").ToString()
// 输出:138****1234
支持路径表达式查询,性能比 gjson
更高。
库名 | 性能优势 | 内存管理 | 适用场景 |
---|---|---|---|
encoding/json | 基准水平 | 高分配次数 | 简单需求、兼容性优先 |
jsoniter | 2-10倍提升 | 内存池复用 | 高并发API、PHP对接 |
sonic | 10-20倍提升 | JIT优化 | 超大规模数据流处理 |
easyjson | 极致性能 | 代码生成 | 固定Schema高频调用 |
gjson | 字段提取优化 | 零内存分配 | 仅需部分字段的场景 |
选型建议:
jsoniter
,API兼容标准库sonic
(需支持AVX指令集)gjson
+jsoniter
组合使用import "github.com/json-iterator/go/extra"
func init() {
extra.RegisterFuzzyDecoders() // 开启PHP兼容模式
extra.SupportPrivateFields() // 支持非导出字段
}
type User struct { ID int `json:"id"` }
file, _ := os.Open("1GB.json")
iter := jsoniter.Parse(jsoniter.ConfigDefault, file, 4096)
for iter.ReadArray() {
user := User{}
iter.ReadVal(&user)
// 流式处理避免OOM
}
jsoniter.RegisterTypeDecoder
预注册高频类型jsoniter.API
实例map[string]interface{}
改用 jsoniter.Get
直接操作type EncoderCache struct {
sync.RWMutex
encoders map[reflect.Type]ValEncoder
}
通过读写锁+哈希表实现高效并发访问。
type Stream struct {
buf []byte
pool *sync.Pool
}
func (s *Stream) Recycle() {
s.buf = s.buf[:0]
s.pool.Put(s)
}
通过对象池复用Stream实例,降低GC压力。
sonic
的向量化处理技术作为平衡性能与易用性的优选方案,jsoniter
尤其适合从PHP/Python等弱类型系统迁移的项目。
尽管Go 1.18后标准库性能有所提升,但在处理嵌套对象、可选字段等复杂场景下,jsoniter
仍保持2倍以上的性能优势。