mirror of https://github.com/goccy/go-json.git
79 lines
1.8 KiB
Go
79 lines
1.8 KiB
Go
package benchmark
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
|
|
gojson "github.com/goccy/go-json"
|
|
)
|
|
|
|
// Benchmark decoding from a slow io.Reader that never fills the buffer completely
|
|
func Benchmark_Decode_SlowReader_EncodingJson(b *testing.B) {
|
|
var expected LargePayload
|
|
if err := json.Unmarshal(LargeFixture, &expected); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
for _, chunkSize := range [5]int{16384, 4096, 1024, 256, 64} {
|
|
b.Run(fmt.Sprintf("chunksize %v", chunkSize), func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
index = 0
|
|
var got LargePayload
|
|
if err := json.NewDecoder(slowReader{chunkSize: chunkSize}).Decode(&got); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(expected, got) {
|
|
b.Fatalf("failed to decode. expected:[%+v] but got:[%+v]", expected, got)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Benchmark_Decode_SlowReader_GoJson(b *testing.B) {
|
|
var expected LargePayload
|
|
if err := json.Unmarshal(LargeFixture, &expected); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
for _, chunkSize := range []int{16384, 4096, 1024, 256, 64} {
|
|
b.Run(fmt.Sprintf("chunksize %v", chunkSize), func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
index = 0
|
|
var got LargePayload
|
|
if err := gojson.NewDecoder(slowReader{chunkSize: chunkSize}).Decode(&got); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(expected, got) {
|
|
b.Fatalf("failed to decode. expected:[%+v] but got:[%+v]", expected, got)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
type slowReader struct {
|
|
chunkSize int
|
|
}
|
|
|
|
var index int
|
|
|
|
func (s slowReader) Read(p []byte) (n int, err error) {
|
|
smallBuf := make([]byte, Min(s.chunkSize, len(p)))
|
|
x := bytes.NewReader(LargeFixture)
|
|
n, err = x.ReadAt(smallBuf, int64(index))
|
|
index += n
|
|
copy(p, smallBuf)
|
|
return
|
|
}
|
|
|
|
func Min(x, y int) int {
|
|
if x < y {
|
|
return x
|
|
}
|
|
return y
|
|
}
|