mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-13 06:07:34 +00:00
util/jsonutil: new package
The cornerstone API is a more memory-efficient Unmarshal. The savings come from re-using a json.Decoder. BenchmarkUnmarshal-8 4016418 288 ns/op 8 B/op 1 allocs/op BenchmarkStdUnmarshal-8 4189261 283 ns/op 184 B/op 2 allocs/op It also includes a Bytes type to reduce allocations when unmarshalling a non-hex-encoded JSON string into a []byte. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:

committed by
Josh Bleecher Snyder

parent
b65eee0745
commit
a5dd0bcb09
65
util/jsonutil/unmarshal_test.go
Normal file
65
util/jsonutil/unmarshal_test.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package jsonutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompareToStd(t *testing.T) {
|
||||
tests := []string{
|
||||
`{}`,
|
||||
`{"a": 1}`,
|
||||
`{]`,
|
||||
`"abc"`,
|
||||
`5`,
|
||||
`{"a": 1} `,
|
||||
`{"a": 1} {}`,
|
||||
`{} bad data`,
|
||||
`{"a": 1} "hello"`,
|
||||
`[]`,
|
||||
` {"x": {"t": [3,4,5]}}`,
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
b := []byte(test)
|
||||
var ourV, stdV interface{}
|
||||
ourErr := Unmarshal(b, &ourV)
|
||||
stdErr := json.Unmarshal(b, &stdV)
|
||||
if (ourErr == nil) != (stdErr == nil) {
|
||||
t.Errorf("Unmarshal(%q): our err = %#[2]v (%[2]T), std err = %#[3]v (%[3]T)", test, ourErr, stdErr)
|
||||
}
|
||||
// if !reflect.DeepEqual(ourErr, stdErr) {
|
||||
// t.Logf("Unmarshal(%q): our err = %#[2]v (%[2]T), std err = %#[3]v (%[3]T)", test, ourErr, stdErr)
|
||||
// }
|
||||
if ourErr != nil {
|
||||
// TODO: if we zero ourV on error, remove this continue.
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(ourV, stdV) {
|
||||
t.Errorf("Unmarshal(%q): our val = %v, std val = %v", test, ourV, stdV)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnmarshal(b *testing.B) {
|
||||
var m interface{}
|
||||
j := []byte("5")
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Unmarshal(j, &m)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStdUnmarshal(b *testing.B) {
|
||||
var m interface{}
|
||||
j := []byte("5")
|
||||
b.ReportAllocs()
|
||||
for i := 0; i < b.N; i++ {
|
||||
json.Unmarshal(j, &m)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user