golang高性能JSON基准测试与分析插件库go-json-benchmark的使用
Golang高性能JSON基准测试与分析插件库go-json-benchmark的使用
简介
这是一个针对JSON包的基准测试库。如果你发现任何错误或过时的信息,欢迎提交issue。
结论
github.com/json-iterator/go
通常是最佳选择,它提供了许多有用的功能、面向对象的设计和高性能。
如何使用
go test -v -bench ./...
或者更详细的性能测试:
GOGC=off go test -bench=. -benchmem
注意:测试结果会因不同环境而异,结果仅供参考。
示例结果
以下是一个示例基准测试结果的部分数据:
测试类型 | 包名 | 操作次数 | ns/op | B/op | allocs/op |
---|---|---|---|---|---|
10Fields_Iterator_Object | jsoniter-readObjCB-8 | 1458022 | 810 | 144 | 14 |
10Fields_Iterator_Object | jsoniter-readObj-8 | 1369156 | 813 | 144 | 14 |
10Fields_Iterator_Object | jsonparser-8 | 1357131 | 908 | 80 | 4 |
10Fields_Unmarshal_Interface | djson-8 | 440643 | 2576 | 1174 | 27 |
10Fields_Unmarshal_Interface | easyjson-8 | 422460 | 2894 | 1174 | 27 |
完整示例代码
package main
import (
"encoding/json"
"fmt"
"testing"
jsoniter "github.com/json-iterator/go"
)
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Age int `json:"age"`
}
func BenchmarkStdJSON(b *testing.B) {
data := []byte(`{"name":"John","email":"john@example.com","age":30}`)
var user User
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = json.Unmarshal(data, &user)
}
}
func BenchmarkJsoniter(b *testing.B) {
data := []byte(`{"name":"John","email":"john@example.com","age":30}`)
var user User
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = jsoniter.Unmarshal(data, &user)
}
}
func main() {
// 示例使用jsoniter
var json = jsoniter.ConfigCompatibleWithStandardLibrary
data := []byte(`{"name":"Alice","email":"alice@example.com","age":25}`)
var user User
if err := json.Unmarshal(data, &user); err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("User: %+v\n", user)
}
已测试的包
仓库 | 版本 | 解组(接口) | 解组(结构体) | 迭代器 | 验证 |
---|---|---|---|---|---|
encoding/json | 1.15.2 | x | x | x | |
github.com/json-iterator/go | 1.1.10 | x | x | x | x |
github.com/buger/jsonparser | 1.0.0 | x | |||
github.com/a8m/djson | c02c5ae | x | |||
github.com/mailru/easyjson | 0.7.6 | x | (1) |
注意事项
- easyjson使用自己的marshaler/unmarshaler,未进行测试
- ujson使用ujson.numeric作为其内部数字类型
- ugorji需要配置才能与标准库兼容
- gjson从v1.4.0开始弃用了其unmarshal方法
- gjson只解码带有标签的结构体字段(<= v1.3.6)
未测试的包
仓库 | 原因 |
---|---|
github.com/Jeffail/gabs | 编码/解码使用encoding/json |
github.com/bitly/go-simplejson | 编码/解码使用encoding/json |
github.com/antonholmquist/jason | 编码/解码使用encoding/json |
github.com/pquerna/ffjson | 编码/解码使用encoding/json(如果未提供自定义接口) |
TODO
- 添加中等和大型负载测试
- 自动基准测试
更多关于golang高性能JSON基准测试与分析插件库go-json-benchmark的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高性能JSON基准测试与分析插件库go-json-benchmark的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
go-json-benchmark: 高性能JSON基准测试与分析插件库
go-json-benchmark 是一个专门用于测试和比较不同Go JSON库性能的工具库,它可以帮助开发者选择最适合自己应用场景的JSON编解码库。
主要特性
- 支持多种主流JSON库的性能测试
- 提供详细的基准测试结果
- 可扩展的架构,方便添加新的JSON库
- 支持自定义数据结构测试
支持的JSON库
- 标准库
encoding/json
json-iterator/go
bytedance/sonic
goccy/go-json
segmentio/encoding
tidwall/gjson
(仅解码)valyala/fastjson
(仅解码)
安装
go get github.com/go-json-benchmark/go-json-benchmark
基本使用示例
package main
import (
"log"
benchmark "github.com/go-json-benchmark/go-json-benchmark"
)
func main() {
// 创建测试实例
b := benchmark.NewBenchmark()
// 添加自定义测试数据结构
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Roles []string `json:"roles"`
IsActive bool `json:"is_active"`
}
// 注册测试数据
b.RegisterData("user", User{
ID: 1,
Name: "John Doe",
Email: "john@example.com",
Roles: []string{"admin", "user"},
IsActive: true,
})
// 运行所有基准测试
results, err := b.RunAll()
if err != nil {
log.Fatal(err)
}
// 打印结果
for _, result := range results {
log.Printf("%s: %s (%.2f ops/sec)\n",
result.Library,
result.Operation,
result.OpsPerSec)
}
// 生成报告
report := benchmark.GenerateReport(results)
log.Println("\nPerformance Report:")
log.Println(report)
}
高级用法
自定义测试选项
// 创建带自定义选项的测试
b := benchmark.NewBenchmark(
benchmark.WithIterations(1000), // 设置迭代次数
benchmark.WithWarmupIterations(100), // 预热迭代
benchmark.WithConcurrency(4), // 并发数
)
测试特定JSON库
// 只测试特定库
results, err := b.Run(
benchmark.EncodingJSON, // 标准库
benchmark.JSONIter, // json-iterator
benchmark.Sonic, // bytedance/sonic
)
自定义基准测试
// 自定义基准测试函数
b.AddCustomBenchmark("custom", "encode", func(data interface{}) error {
// 自定义编码逻辑
return nil
})
b.AddCustomBenchmark("custom", "decode", func(data interface{}) error {
// 自定义解码逻辑
return nil
})
结果分析
go-json-benchmark 提供多种结果分析方式:
- 原始数据:每次操作的纳秒时间、每秒操作数
- 比较报告:不同库之间的性能对比
- 内存分配:每次操作的内存分配情况
- 相对性能:相对于标准库的性能提升百分比
性能优化建议
根据测试结果,以下是一些通用的性能优化建议:
- 高并发场景:考虑使用
bytedance/sonic
或goccy/go-json
- 内存敏感应用:
segmentio/encoding
通常有更好的内存表现 - 只读JSON处理:
gjson
或fastjson
提供最快的解码速度 - 兼容性优先:标准库
encoding/json
仍然是兼容性最好的选择
注意事项
- 不同数据结构可能导致不同JSON库的性能表现不同
- 实际应用中的性能可能与基准测试有差异
- 新版本发布后建议重新测试,因为各库的性能会不断优化
通过使用 go-json-benchmark,开发者可以基于实际数据而非直觉来选择JSON处理库,从而为应用选择最优的JSON解决方案。