之前分享了一个高性能的 Go JSON 解析库 gjson,今天分享下与其类似的库。
1. jsonparser - 高性能选择
1
2
3
4
5
6
7
8
9
10
11
12
import "github.com/buger/jsonparser"
// 特点:零内存分配,性能极致
data := [] byte ( `{"name":"张三","age":25}` )
name , err := jsonparser . GetString ( data , "name" )
age , err := jsonparser . GetInt ( data , "age" )
// 遍历数组
jsonparser . ArrayEach ( data , func ( value [] byte , dataType jsonparser . ValueType , offset int , err error ) {
// 处理每个元素
}, "users" )
优势
:性能最高,内存效率最好
劣势
:API 相对复杂
2. ffjson - 代码生成方式
1
2
3
4
5
6
7
8
9
10
11
12
// 生成优化代码
// go get -u github.com/pquerna/ffjson
// ffjson user.go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// 使用生成的优化方法
var user User
err := user . UnmarshalJSON ( data )
优势
:运行时性能好
劣势
:需要代码生成步骤
3. easyjson - 另一个代码生成方案
1
2
3
4
5
6
7
8
9
10
11
// 类似 ffjson,但更活跃
//go:generate easyjson -all user.go
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
// 使用生成的优化方法
var user User
user . UnmarshalJSON ( data )
优势
:性能优秀,活跃维护
劣势
:需要代码生成
4. go-json - 标准库的替代品
1
2
3
4
5
6
7
8
9
import "github.com/goccy/go-json"
// 完全兼容标准库,但性能更好
var data map [ string ] interface {}
err := json . Unmarshal ( jsonData , & data )
// 支持 JSONPath 查询
var value interface {}
err := json . UnmarshalWithOption ( data , & value , json . Path ( "store.book[0].title" ))
优势
:兼容标准库,性能提升明显
劣势
:功能相对简单
5. fastjson - 纯解析器
1
2
3
4
5
6
7
import "github.com/valyala/fastjson"
var p fastjson . Parser
v , err := p . Parse ( `{"user": {"name": "张三"}}` )
name := v . GetStringBytes ( "user" , "name" )
age := v . GetInt ( "user" , "age" )
优势
:解析速度快
劣势
:API 不够友好
6. 各库性能对比(粗略排名)
7. 选择建议
7.1 选择 gjson 当:
1
2
3
4
5
6
7
8
9
// 适合场景:
- API响应结构不确定或经常变化
- 只需要提取少量字段
- 快速原型开发
- 处理复杂的JSON路径查询
// 示例:第三方API数据提取
url := gjson . Get ( apiResponse , "data.results.0.url" ). String ()
title := gjson . Get ( apiResponse , "data.results.0.title" ). String ()
7.2 选择 jsonparser 当:
1
2
3
4
5
6
7
8
9
10
11
12
13
// 适合场景:
- 高性能要求极致
- 处理超大JSON文件
- 内存敏感环境
// 示例:日志处理
jsonparser . EachKey ( logData , func ( idx int , value [] byte , vt jsonparser . ValueType , err error ) {
// 高性能处理
}, [][] string {
{ "timestamp" },
{ "level" },
{ "message" },
})
7.3 选择 easyjson/ffjson 当:
1
2
3
4
5
6
7
8
9
10
// 适合场景:
- 数据结构固定且频繁序列化
- 微服务间通信
- 需要最佳运行时性能
// 示例:微服务API
//go:generate easyjson -all model.go
type APIResponse struct {
Data [] User `json:"data"`
}
7.4 选择标准库当:
1
2
3
4
5
6
7
8
9
10
11
12
13
// 适合场景:
- 简单的数据结构
- 可读性优先
- 团队技术栈统一
- 不需要极致性能
// 示例:配置解析
type Config struct {
Host string `json:"host"`
Port int `json:"port"`
}
var config Config
json . Unmarshal ( data , & config )
8. 实际项目中的选择策略
8.1 小型项目/脚本工具
推荐 gjson
8.2 高性能后端服务
推荐组合使用:
1
2
3
4
5
6
7
8
9
10
11
// 主要业务逻辑用标准库或easyjson
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
// 第三方API集成用gjson
func parseExternalAPI ( response [] byte ) {
externalID := gjson . GetBytes ( response , "external_user.id" ). String ()
// ... 其他复杂提取逻辑
}
8.3 数据管道/ETL工具
推荐 jsonparser:
9. 总结
大多数情况下,gjson 是最平衡的选择,既保证了开发效率,又有不错的性能。