Add benchmark for stream decoding

This commit is contained in:
Masaaki Goshima 2020-07-31 12:22:00 +09:00
parent 20b67ad48d
commit 961b6a202e
4 changed files with 31 additions and 9 deletions

View File

@ -1,6 +1,7 @@
package benchmark package benchmark
import ( import (
"bytes"
"encoding/json" "encoding/json"
"testing" "testing"
@ -49,6 +50,17 @@ func Benchmark_Decode_SmallStruct_GoJayUnsafe(b *testing.B) {
} }
} }
func Benchmark_Decode_SmallStruct_GoJsonDecode(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
result := SmallPayload{}
buf := bytes.NewBuffer(SmallFixture)
if err := gojson.NewDecoder(buf).Decode(&result); err != nil {
b.Fatal(err)
}
}
}
func Benchmark_Decode_SmallStruct_GoJson(b *testing.B) { func Benchmark_Decode_SmallStruct_GoJson(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {

View File

@ -2,7 +2,6 @@ package json
import ( import (
"encoding" "encoding"
"fmt"
"io" "io"
"reflect" "reflect"
"strconv" "strconv"

View File

@ -64,6 +64,7 @@ func (d *intDecoder) decodeStreamByte(s *stream) ([]byte, error) {
break break
} }
num := s.buf[start:s.cursor] num := s.buf[start:s.cursor]
s.reset()
if len(num) < 2 { if len(num) < 2 {
return nil, errInvalidCharacter(s.char(), "number(integer)", s.totalOffset()) return nil, errInvalidCharacter(s.char(), "number(integer)", s.totalOffset())
} }
@ -77,6 +78,7 @@ func (d *intDecoder) decodeStreamByte(s *stream) ([]byte, error) {
break break
} }
num := s.buf[start:s.cursor] num := s.buf[start:s.cursor]
s.reset()
return num, nil return num, nil
default: default:
return nil, errInvalidCharacter(s.char(), "number(integer)", s.totalOffset()) return nil, errInvalidCharacter(s.char(), "number(integer)", s.totalOffset())

View File

@ -63,20 +63,29 @@ func (s *stream) reset() {
} }
func (s *stream) read() bool { func (s *stream) read() bool {
if s.allRead {
return false
}
buf := make([]byte, readChunkSize) buf := make([]byte, readChunkSize)
n, err := s.r.Read(buf) n, err := s.r.Read(buf)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return false return false
} }
remain := s.length if n < readChunkSize || err == io.EOF {
newBuf := make([]byte, remain+int64(n)+1)
copy(newBuf, s.buf)
copy(newBuf[remain:], buf)
s.buf = newBuf
s.length = int64(len(newBuf)) - 1
s.offset += s.cursor
if n == 0 || err == io.EOF {
s.allRead = true s.allRead = true
}
totalSize := s.length + int64(n) + 1
if totalSize > readChunkSize {
newBuf := make([]byte, totalSize)
copy(newBuf, s.buf)
copy(newBuf[s.length:], buf)
s.buf = newBuf
} else {
s.buf = buf
}
s.length = int64(len(s.buf)) - 1
s.offset += s.cursor
if n == 0 {
return false return false
} }
return true return true