Sonic 是字节跳动开源的一款 Go 语言 JSON 解析库,按照官方的说法:
自 2021 年 7 月份发布以来,Sonic 已被抖音、今日头条等业务采用,累计为字节跳动节省了数十万 CPU 核(省了好多钱啊~)。
下面我们来看 Sonic 相比其他 JSON 解析库优势有多大,以及常见的使用举例。
测试结果如下:结果显示:目前这些 JSON 库均无法在各场景下都保持最优性能,即使是当前使用最广泛的第三方库 Json-iterator,在泛型编解码、大数据量级场景下的性能也满足不了字节的需求。
JSON 库的基准编解码性能固然重要,但是对不同场景的最优匹配更关键 —— 于是字节走上了自研 JSON 库的道路。
以下是字节根据上面的不同场景进行的测试结果:
可以看到 Sonic 在大部分场景下都有明显的优势:
通过上面的测试比较结果,我们很难不想去使用 Sonic 去优化我们的业务,为我们自己的系统提效添砖加瓦~
使用 Sonic 将 JSON 数据解析为 map 类型的方法:
例如:
package main
import (
"github.com/bytedance/sonic"
"fmt"
)
func main() {
var jsonStr = `{"name": "Harper", "age": 18}`
var data map[string]any
err := sonic.Unmarshal([]byte(jsonStr), &data)
if err != nil {
fmt.Println("解析失败:", err)
}
fmt.Println(data["name"], data["age"])
}
使用 Sonic 将 JSON 数据解析为结构体类型的方法:
例如:
package main
import (
"github.com/bytedance/sonic"
"fmt"
)
func main() {
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
var jsonStr = `{"name": "Harper", "age": 20}`
var person Person
err := sonic.Unmarshal([]byte(jsonStr), &person)
if err != nil {
fmt.Println("解析失败:", err)
}
fmt.Println(person.Name, person.Age)
}
Sonic 可以解析嵌套的 JSON 数据,其实跟上面的「解析为结构体类型」原因一样,例如:
package main
import (
"github.com/bytedance/sonic"
"fmt"
)
func main() {
var jsonStr = `{"name": "Harper", "age": 30, "address": {"city": "HaiDian Beijing", "country": "China"}}`
type Address struct {
City string `json:"city"`
Country string `json:"country"`
}
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Address Address `json:"address"`
}
var person Person
err := sonic.Unmarshal([]byte(jsonStr), &person)
if err != nil {
fmt.Println("解析失败:", err)
}
fmt.Println(person.Name, person.Age, person.Address.City, person.Address.Country)
}
Sonic 还可以解析数组类型的 JSON 数据,例如:
package main
import (
"github.com/bytedance/sonic"
"fmt"
)
func main() {
var jsonStr = `[{"name": "Harper", "age": 33}, {"name": "Bella", "age": 34}]`
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
var persons []Person
err := sonic.Unmarshal([]byte(jsonStr), &persons)
if err != nil {
fmt.Println("解析失败:", err)
}
for _, person := range persons {
fmt.Println(person.Name, person.Age)
}
}
Sonic 是一款高性能的 JSON 解析库,它提供了丰富的 JSON 解析 API,包括解析为 map、结构体、嵌套 JSON 数据和数组类型等,涵盖了我们工作中几乎所有的应用场景。
特别是对于大数据解析的场景,如果我们系统遇到了 JSON 数据解析的瓶颈,不妨试试 Sonic,看看效果,毕竟替换很方便,跟 Json-iterator 类似,平替成本很低。
【参考资料】
(全文完)