go json包 json、json-iterator、gjson、easyjson使用
区别:
- json 是go自带的json编码与解码包。
- json-iterator是目前github上star最多的json编码与解码包。效率高。并且可以通过简单的代码替换官方json方法。
- gjson则用来进行json解码,或者从json中获取数据。没有编码方法
- easyjson则通过预先生成编码与解码方法,避免反射来提高效率。但暂时没有发现对列表的支持。而且以前测试过,暂时不测了。
版本:
go | json-iterator | gjson |
---|---|---|
go1.13.5 | v1.1.9 | v1.6.0 |
测试编码:
modles.go
type Student struct {
Name string `json:"name"`
Age int8 `json:"age"`
}
type Animal struct {
Name string `json:"Name"`
Order string `json:"Order"`
}
unmarshal_test.go
package jsoniter
import (
"encoding/json"
"fmt"
jsoniter "github.com/json-iterator/go"
"github.com/luslin/tools/jsoniter/modles"
"github.com/tidwall/gjson"
"testing"
)
var jsonBlob = []byte(`[
{"name": "Platypus", "order": "Monotremata"},
{"name": "Quoll", "order": "Dasyuromorphia"}
]`)
var animals []modles.Animal
func TestJsoniterUnmarshal(t *testing.T) {
err := jsoniter.Unmarshal(jsonBlob, &animals)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v", animals)
}
func BenchmarkJsoniterUnmarshal(b *testing.B) {
for i := 0; i < b.N; i++ {
jsoniter.Unmarshal(jsonBlob, &animals)
}
}
func TestJsonUnmarshal(t *testing.T) {
err := json.Unmarshal(jsonBlob, &animals)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v", animals)
}
func BenchmarkJsonUnmarshal(b *testing.B) {
for i := 0; i < b.N; i++ {
json.Unmarshal(jsonBlob, &animals)
}
}
func TestGjsonUnmarshal(t *testing.T) {
animals = animals[:0]
results := gjson.ParseBytes(jsonBlob).Array()
for _, result := range results{
animal := modles.Animal{}
animal.Name = result.Get("Name").String()
animal.Order = result.Get("Order").String()
animals = append(animals, animal)
}
fmt.Printf("%+v", animals)
}
func BenchmarkGjsonUnmarshal(b *testing.B) {
for i := 0; i < b.N; i++ {
results := gjson.ParseBytes(jsonBlob).Array()
for _, result := range results{
animal := modles.Animal{}
animal.Name = result.Get("Name").String()
animal.Order = result.Get("Order").String()
animals = append(animals, animal)
animals = animals[:0]
}
}
}
marshal_test.go
package jsoniter
import (
"encoding/json"
"fmt"
jsoniter "github.com/json-iterator/go"
"github.com/luslin/tools/jsoniter/modles"
"strconv"
"testing"
)
var students []modles.Student
func init() {
students = make([]modles.Student,0,10)
for i := 0; i < 10; i++ {
students = append(students, modles.Student{
Name: "s" + strconv.Itoa(i),
Age: int8(i + 20),
})
}
}
func TestJsonitermarshal(t *testing.T) {
studentStr, err := jsoniter.MarshalToString(students)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%s", studentStr)
}
func BenchmarkJsonitermarshal(b *testing.B) {
for i := 0; i < b.N; i++ {
jsoniter.Marshal(students)
}
}
func TestJsonmarshal(t *testing.T) {
student_bytes, err := json.Marshal(students)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%s", string(student_bytes))
}
func BenchmarkJsonmarshal(b *testing.B) {
for i := 0; i < b.N; i++ {
json.Marshal(students)
}
}
批量测试发现:
- marshal时,json 与 jsonitor 差别不是很大,但大部分情况jsonitor 的性能要稍好一些
- unmarshal时, jsonitor的效率最高,gsjon其次,json 最差
BenchmarkJsonitermarshal-4 838011 1532 ns/op
BenchmarkJsonmarshal-4 852482 1568 ns/op
BenchmarkJsoniterUnmarshal-4 2188299 554 ns/op
BenchmarkJsonUnmarshal-4 582736 2280 ns/op
BenchmarkGjsonUnmarshal-4 1397656 910 ns/op