Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: use integers.json file to benchmark integer decoder #42

Merged
merged 3 commits into from Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions dec_int.go
Expand Up @@ -8,13 +8,14 @@ import (
"github.com/go-faster/errors"
)

var intDigits []int8
var intDigits [256]int8

const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
const (
uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1
uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1
)

func init() {
intDigits = make([]int8, 256)
for i := 0; i < len(intDigits); i++ {
intDigits[i] = invalidCharForNumber
}
Expand Down
60 changes: 41 additions & 19 deletions dec_int_test.go
Expand Up @@ -7,28 +7,50 @@ import (
)

func BenchmarkDecoder_Int(b *testing.B) {
data := []byte(`69315063`)
d := GetDecoder()
for i := 0; i < b.N; i++ {
d.ResetBytes(data)
if _, err := d.Int(); err != nil {
b.Fatal(err)
}
}
runTestdataFile("integers.json", b.Fatal, func(name string, data []byte) {
b.Run(name, func(b *testing.B) {
d := GetDecoder()
cb := func(d *Decoder) error {
_, err := d.Int()
return err
}
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
d.ResetBytes(data)

if err := d.Arr(cb); err != nil {
b.Fatal(err)
}
}
})
})
}

func BenchmarkDecoder_Uint(b *testing.B) {
data := []byte(`69315063`)
d := GetDecoder()
for i := 0; i < b.N; i++ {
d.ResetBytes(data)
if _, err := d.UInt(); err != nil {
b.Fatal(err)
}
}
runTestdataFile("integers.json", b.Fatal, func(name string, data []byte) {
b.Run(name, func(b *testing.B) {
d := GetDecoder()
cb := func(d *Decoder) error {
_, err := d.UInt()
return err
}
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
d.ResetBytes(data)

if err := d.Arr(cb); err != nil {
b.Fatal(err)
}
}
})
})
}

func TestDecoder_int_sizes(t *testing.T) {
func TestDecoderIntSizes(t *testing.T) {
data := []byte(`69315063`)
d := GetDecoder()
for _, size := range []int{32, 64} {
Expand All @@ -39,7 +61,7 @@ func TestDecoder_int_sizes(t *testing.T) {
}
}

func TestDecoder_uint_sizes(t *testing.T) {
func TestDecoderUintSizes(t *testing.T) {
data := []byte(`69315063`)
d := GetDecoder()
for _, size := range []int{32, 64} {
Expand All @@ -56,7 +78,7 @@ func TestDecoder_Int(t *testing.T) {
return &Decoder{
buf: []byte{'1', '2'},
tail: 2,
reader: errReader{},
reader: r,
}
}
t.Run("32", func(t *testing.T) {
Expand Down
31 changes: 18 additions & 13 deletions dec_test.go
Expand Up @@ -12,8 +12,8 @@ import (
"github.com/stretchr/testify/require"
)

func runTestCases(t *testing.T, cases []string, cb func(t *testing.T, d *Decoder) error) {
testCase := func(d *Decoder, input string, valid bool) func(t *testing.T) {
func createTestCase(input string, cb func(t *testing.T, d *Decoder) error) func(t *testing.T) {
run := func(d *Decoder, input string, valid bool) func(t *testing.T) {
return func(t *testing.T) {
t.Cleanup(func() {
if t.Failed() {
Expand All @@ -29,21 +29,26 @@ func runTestCases(t *testing.T, cases []string, cb func(t *testing.T, d *Decoder
}
}
}
for i, input := range cases {

return func(t *testing.T) {
valid := json.Valid([]byte(input))

t.Run(fmt.Sprintf("Test%d", i), func(t *testing.T) {
t.Run("Buffer", testCase(DecodeStr(input), input, valid))
t.Run("Buffer", run(DecodeStr(input), input, valid))

r := strings.NewReader(input)
d := Decode(r, 512)
t.Run("Reader", testCase(d, input, valid))
r := strings.NewReader(input)
d := Decode(r, 512)
t.Run("Reader", run(d, input, valid))

r.Reset(input)
obr := iotest.OneByteReader(r)
d.Reset(obr)
t.Run("OneByteReader", testCase(d, input, valid))
})
r.Reset(input)
obr := iotest.OneByteReader(r)
d.Reset(obr)
t.Run("OneByteReader", run(d, input, valid))
}
}

func runTestCases(t *testing.T, cases []string, cb func(t *testing.T, d *Decoder) error) {
for i, input := range cases {
t.Run(fmt.Sprintf("Test%d", i), createTestCase(input, cb))
}
}

Expand Down
6 changes: 3 additions & 3 deletions enc_test.go
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/require"
)

func TestEncoder_byte_should_grow_buffer(t *testing.T) {
func TestEncoderByteShouldGrowBuffer(t *testing.T) {
should := require.New(t)
e := GetEncoder()
e.byte('1')
Expand Down Expand Up @@ -41,14 +41,14 @@ func TestEncoder(t *testing.T) {
})
}

func TestEncoder_Raw_should_grow_buffer(t *testing.T) {
func TestEncoderRawShouldGrowBuffer(t *testing.T) {
should := require.New(t)
e := GetEncoder()
e.RawStr("123")
should.Equal("123", string(e.Bytes()))
}

func TestEncoder_Str_should_grow_buffer(t *testing.T) {
func TestEncoderStrShouldGrowBuffer(t *testing.T) {
should := require.New(t)
e := GetEncoder()
e.Str("123")
Expand Down
119 changes: 90 additions & 29 deletions int_test.go
@@ -1,11 +1,11 @@
package jx

import (
"bytes"
"fmt"
"io"
"math"
"strconv"
"strings"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -73,26 +73,56 @@ func TestDecoderIntNumbers(t *testing.T) {
}

func TestReadInt32(t *testing.T) {
inputs := []string{`1`, `12`, `123`, `1234`, `12345`, `123456`, `2147483647`, `-2147483648`}
for _, input := range inputs {
t.Run(input, func(t *testing.T) {
inputs := []string{
`-12`,
`-1`,
`0`,
`1`,
`12`,
`123`,
`1234`,
`12345`,
`123456`,
`1234567`,
`12345678`,
`123456789`,
`1234567890`,
`2147483647`,
`-2147483648`,
}
for i, input := range inputs {
input := input
t.Run(fmt.Sprintf("Test%d", i+1), createTestCase(input, func(t *testing.T, d *Decoder) error {
should := require.New(t)
iter := DecodeStr(input)
expected, err := strconv.ParseInt(input, 10, 32)
should.NoError(err)
v, err := iter.Int32()
v, err := d.Int32()
should.NoError(err)
should.Equal(int32(expected), v)
})
t.Run(input, func(t *testing.T) {
return nil
}))
}

{
input := "[" + strings.Join(inputs, ",") + "]"
t.Run("Array", createTestCase(input, func(t *testing.T, d *Decoder) error {
should := require.New(t)
iter := Decode(bytes.NewBufferString(input), 2)
expected, err := strconv.ParseInt(input, 10, 32)
should.NoError(err)
v, err := iter.Int32()
should.NoError(err)
should.Equal(int32(expected), v)
})
i := 0

return d.Arr(func(d *Decoder) error {
expected, err := strconv.ParseInt(inputs[i], 10, 32)
should.NoError(err)

v, err := d.Int32()
if err != nil {
return err
}
should.Equal(int32(expected), v)

i++
return nil
})
}))
}
}

Expand Down Expand Up @@ -175,26 +205,57 @@ func TestReadInt64Overflow(t *testing.T) {
}

func TestReadInt64(t *testing.T) {
inputs := []string{`1`, `12`, `123`, `1234`, `12345`, `123456`, `9223372036854775807`, `-9223372036854775808`}
for _, input := range inputs {
t.Run(input, func(t *testing.T) {
inputs := []string{
`-12`,
`-1`,
`0`,
`1`,
`12`,
`123`,
`1234`,
`12345`,
`123456`,
`1234567`,
`12345678`,
`123456789`,
`1234567890`,
`12345678901`,
`9223372036854775807`,
`-9223372036854775808`,
}
for i, input := range inputs {
input := input
t.Run(fmt.Sprintf("Test%d", i+1), createTestCase(input, func(t *testing.T, d *Decoder) error {
should := require.New(t)
iter := DecodeStr(input)
expected, err := strconv.ParseInt(input, 10, 64)
should.NoError(err)
v, err := iter.Int64()
v, err := d.Int64()
should.NoError(err)
should.Equal(expected, v)
})
t.Run(input, func(t *testing.T) {
return nil
}))
}

{
input := "[" + strings.Join(inputs, ",") + "]"
t.Run("Array", createTestCase(input, func(t *testing.T, d *Decoder) error {
should := require.New(t)
iter := Decode(bytes.NewBufferString(input), 2)
expected, err := strconv.ParseInt(input, 10, 64)
should.NoError(err)
v, err := iter.Int64()
should.NoError(err)
should.Equal(expected, v)
})
i := 0

return d.Arr(func(d *Decoder) error {
expected, err := strconv.ParseInt(inputs[i], 10, 64)
should.NoError(err)

v, err := d.Int64()
if err != nil {
return err
}
should.Equal(expected, v)

i++
return nil
})
}))
}
}

Expand Down