Go 生态最快 JSON 库 - jsoniter
jsoniter)是高性能 JSON 编解码库,性能是 Go 标准库 encoding/json 的 3-10 倍,同时完全兼容标准库 API,替换成本极低。它通过零堆内存分配、SIMD 指令优化、流式处理等技术,在高并发、大数据量的 JSON 处理场景下表现极其出色,是目前 Go 后端开发的首选 JSON 库。
环境搭建
Go 版本 ≥ 1.12
# 安装 jsoniter 核心库
go get github.com/json-iterator/go
核心 API 详解
jsoniter 最大的优势之一是完全兼容标准库 encoding/json 的 API,你可以直接替换导入语句,无需修改业务代码即可获得性能提升;同时它还提供了更便捷、更高性能的专属 API,覆盖 99% 的开发场景。
如果你之前用的是标准库 encoding/json,只需把导入语句换成 jsoniter,代码一行都不用改,性能直接提升。
- 零成本替换:只需替换导入语句,所有标准库 API 都能直接用,这是
jsoniter最友好的一点。 - Tag 完全兼容:标准库的
json:"tag"完全支持,无需修改。
| API | 作用 | 标准库对比 |
|---|---|---|
jsoniter.Marshal(&obj) | 序列化:结构体 → JSON 字节串 | 完全兼容 json.Marshal |
jsoniter.Unmarshal(data, &obj) | 反序列化:JSON 字节串 → 结构体 | 完全兼容 json.Unmarshal |
jsoniter.NewEncoder(w).Encode(&obj) | 流式序列化:直接写入 io.Writer | 完全兼容 json.Encoder |
jsoniter.NewDecoder(r).Decode(&obj) | 流式反序列化:直接从 io.Reader 读取 | 完全兼容 json.Decoder |
// 定义模型
type User struct {
ID uint `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
Age uint `json:"age"`
}
func main() {
// 1. 序列化:结构体 → JSON
user := User{ID: 1, Username: "zhangsan", Email: "zhangsan@example.com", Age: 20}
jsonData, err := jsoniter.Marshal(&user)
if err != nil {
fmt.Printf("序列化失败:%v\n", err)
return
}
fmt.Printf("序列化结果:%s\n", jsonData)
// 2. 反序列化:JSON → 结构体
var newUser User
if err := jsoniter.Unmarshal(jsonData, &newUser); err != nil {
fmt.Printf("反序列化失败:%v\n", err)
return
}
fmt.Printf("反序列化结果:%+v\n", newUser)
}
高性能便捷 API(jsoniter 专属)
| API | 作用 | 优势 |
|---|---|---|
jsoniter.MarshalToString(&obj) | 序列化:结构体 → JSON 字符串 | 直接返回字符串,无需手动转换 []byte,性能更高 |
jsoniter.UnmarshalFromString(data, &obj) | 反序列化:JSON 字符串 → 结构体 | 直接接收字符串参数,无需手动转换 []byte |
jsoniter.Get(data, path).Any() | 部分解析:只读取 JSON 中指定字段的值 | 无需解析整个 JSON,性能极高,适合只需要部分字段的场景 |
序列化到字符串
user := User{ID: 1, Username: "zhangsan", Email: "zhangsan@example.com", Age: 20}
// 直接返回 string,无需 string(jsonData) 转换
jsonStr, err := jsoniter.MarshalToString(&user)
if err != nil {
fmt.Printf("序列化失败:%v\n", err)
return
}
fmt.Printf("序列化字符串:%s\n", jsonStr)
从字符串反序列化
var newUser User
// 直接接收 string,无需 []byte(jsonStr) 转换
if err := jsoniter.UnmarshalFromString(jsonStr, &newUser); err != nil {
fmt.Printf("反序列化失败:%v\n", err)
return
}
fmt.Printf("反序列化结果:%+v\n", newUser)
部分解析(Get): 只读取需要的字段,无需解析整个 JSON
// 场景:只需要 JSON 中的 username,不需要解析整个结构体
jsonData := []byte(`{"id":1,"username":"zhangsan","email":"zhangsan@example.com","age":20}`)
// Get 路径:"username",直接获取该字段的值
username := jsoniter.Get(jsonData, "username").ToString()
age := jsoniter.Get(jsonData, "age").ToUint()
fmt.Printf("部分解析:username=%s, age=%d\n", username, age)
MarshalToString/UnmarshalFromString:避免了[]byte和string的手动转换,代码更简洁,性能更高(减少内存拷贝)。Get部分解析:这是jsoniter的杀手级功能,无需解析整个 JSON,直接通过路径读取指定字段,性能提升 10 倍以上,特别适合只需要 JSON 中少数字段的场景(如日志解析、第三方接口回调只取部分数据)。
底层高性能 API(Iterator/Stream,极致性能)
如果你对性能有极致要求(如高并发网关、日志处理系统),jsoniter 提供了底层的 Iterator(反序列化)和 Stream(序列化) API,可实现零堆内存分配,性能达到极致。
| API | 作用 | 适用场景 |
|---|---|---|
jsoniter.ParseBytes(data) | 创建 Iterator,从字节串解析 | 高性能反序列化 |
jsoniter.NewStream(cfg, w, bufSize) | 创建 Stream,序列化到 io.Writer | 高性能序列化 |
jsonData := []byte(`{"id":1,"username":"zhangsan","email":"zhangsan@example.com","age":20}`)
// 创建 Iterator
iter := jsoniter.ParseBytes(jsonData)
// 手动解析字段(按 JSON 顺序读取,性能最高)
var id uint
var username string
// 读取对象开始
iter.ReadObjectCB(func(iter *jsoniter.Iterator, field string) bool {
switch field {
case "id":
id = iter.ReadUint()
case "username":
username = iter.ReadString()
default:
// 跳过不需要的字段
iter.Skip()
}
return true // 继续读取下一个字段
})
if iter.Error != nil {
fmt.Printf("解析失败:%v\n", iter.Error)
return
}
fmt.Printf("Iterator 解析结果:id=%d, username=%s\n", id, username)
适用场景:
- 极致性能要求:如每秒处理百万级 JSON 的日志系统、高并发 API 网关。
- 内存敏感场景:
Iterator/Stream可实现零堆内存分配,大幅降低 GC 压力。
全局配置:忽略未知字段
标准库默认会在反序列化时遇到未知字段报错(除非使用 DisallowUnknownFields),jsoniter 可通过全局配置默认忽略未知字段,更符合实际开发场景。
- 并发安全:全局配置的
jsoniter实例是并发安全的,可在多个 goroutine 中同时使用。
// 配置全局 jsoniter 实例
var json = jsoniter.Config{
// 忽略未知字段:反序列化时遇到 JSON 中有但结构体中没有的字段,直接跳过,不报错
DisallowUnknownFields: false,
// 其他配置...
}.Froze()
type User struct {
Username string `json:"username"`
}
func main() {
// JSON 中有 email 字段,但 User 结构体中没有
jsonStr := `{"username":"zhangsan","email":"zhangsan@example.com"}`
var user User
// 使用全局配置的 json 实例
if err := json.UnmarshalFromString(jsonStr, &user); err != nil {
fmt.Printf("反序列化失败:%v\n", err)
return
}
fmt.Printf("忽略未知字段结果:%+v\n", user)
}