Skip to content

Commit

Permalink
fix: merge skipNumber sets to reduce cache load
Browse files Browse the repository at this point in the history
name             old time/op    new time/op    delta
Valid/Big-12       3.98µs ± 5%    3.60µs ± 2%   -9.63%  (p=0.000 n=25+24)
Valid/Floats-12    3.23µs ± 4%    2.91µs ± 1%   -9.92%  (p=0.000 n=25+24)

name             old speed      new speed      delta
Valid/Big-12      657MB/s ± 5%   727MB/s ± 2%  +10.61%  (p=0.000 n=25+24)
Valid/Floats-12   720MB/s ± 3%   799MB/s ± 1%  +10.98%  (p=0.000 n=25+24)
  • Loading branch information
tdakkota committed Jan 13, 2022
1 parent efb411f commit 16f5d51
Showing 1 changed file with 27 additions and 22 deletions.
49 changes: 27 additions & 22 deletions dec_skip.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,7 @@ func (d *Decoder) skipThreeBytes(b1, b2, b3 byte) error {
}

var (
closerSet = [256]byte{
',': 1,
']': 1,
'}': 1,
' ': 1,
'\t': 1,
'\n': 1,
'\r': 1,
}
digitSet = [256]byte{
skipNumberSet = [256]byte{
'0': 1,
'1': 1,
'2': 1,
Expand All @@ -117,13 +108,25 @@ var (
'7': 1,
'8': 1,
'9': 1,

',': 2,
']': 2,
'}': 2,
' ': 2,
'\t': 2,
'\n': 2,
'\r': 2,
}
)

// skipNumber reads one JSON number.
//
// Assumes d.buf is not empty.
func (d *Decoder) skipNumber() error {
const (
digitTag byte = 1
closerTag byte = 2
)
c := d.buf[d.head]
d.head++
switch c {
Expand All @@ -133,7 +136,7 @@ func (d *Decoder) skipNumber() error {
return err
}
// Character after '-' must be a digit.
if digitSet[c] == 0 {
if skipNumberSet[c] != digitTag {
return badToken(c)
}
if c != '0' {
Expand All @@ -154,7 +157,7 @@ func (d *Decoder) skipNumber() error {
}

c = d.buf[d.head]
if closerSet[c] != 0 {
if skipNumberSet[c] == closerTag {
return nil
}
switch c {
Expand All @@ -168,13 +171,14 @@ func (d *Decoder) skipNumber() error {
}
for {
for i, c := range d.buf[d.head:d.tail] {
if closerSet[c] != 0 {
switch skipNumberSet[c] {
case closerTag:
d.head += i
return nil
}
if digitSet[c] != 0 {
case digitTag:
continue
}

switch c {
case '.':
d.head += i
Expand Down Expand Up @@ -203,18 +207,19 @@ stateDot:
var last byte = '.'
for {
for i, c := range d.buf[d.head:d.tail] {
if closerSet[c] != 0 {
switch skipNumberSet[c] {
case closerTag:
d.head += i
// Check that dot is not last character.
if last == '.' {
return io.ErrUnexpectedEOF
}
return nil
}
if digitSet[c] != 0 {
case digitTag:
last = c
continue
}

switch c {
case 'e', 'E':
if last == '.' {
Expand Down Expand Up @@ -249,14 +254,14 @@ stateExp:
if err != nil {
return err
}
if digitSet[numOrSign] == 0 {
if skipNumberSet[numOrSign] == 0 {
// There must be a number after e.
if numOrSign == '-' || numOrSign == '+' {
num, err := d.byte()
if err != nil {
return err
}
if digitSet[num] == 0 {
if skipNumberSet[num] == 0 {
return badToken(num)
}
} else {
Expand All @@ -266,11 +271,11 @@ stateExp:
}
for {
for i, c := range d.buf[d.head:d.tail] {
if closerSet[c] != 0 {
if skipNumberSet[c] == closerTag {
d.head += i
return nil
}
if digitSet[c] == 0 {
if skipNumberSet[c] == 0 {
return badToken(c)
}
}
Expand Down

0 comments on commit 16f5d51

Please sign in to comment.