diff options
author | Adam Scarr <adam@vektah.net> | 2017-08-06 23:32:10 +1000 |
---|---|---|
committer | Adam Scarr <adam@vektah.net> | 2017-08-06 23:32:10 +1000 |
commit | 666ea93dba377f267a2c8ecf97378a420db18383 (patch) | |
tree | 5efee0b6e4ccf44b854d9bb65e4e6fa5e7f86548 /json | |
parent | 9d7779e8ca5404f26abbd8cce0314d9cee967bba (diff) |
Eliminate a bunch of allocations
Diffstat (limited to 'json')
-rw-r--r-- | json/json.go | 20 | ||||
-rw-r--r-- | json/json_test.go | 42 | ||||
-rw-r--r-- | json/profile/cpuprofile.bat | 2 | ||||
-rw-r--r-- | json/profile/json.go | 4 | ||||
-rw-r--r-- | json/profile/memprofile.bat | 2 |
5 files changed, 36 insertions, 34 deletions
diff --git a/json/json.go b/json/json.go index 3aa5163..60c5a3f 100644 --- a/json/json.go +++ b/json/json.go @@ -9,15 +9,15 @@ import ( var ( value Parser - array = Map(And(WS, "[", Kleene(&value, And(WS, ",")), "]"), func(n Node) Node { - return n.([]Node)[1].([]Node) + array = Map(And(WS, "[", Kleene(&value, And(WS, ",")), "]"), func(n interface{}) interface{} { + return n.([]interface{})[1].([]interface{}) }) properties = Kleene(And(WS, String('"'), WS, ":", WS, &value), ",") - object = Map(And(WS, "{", WS, properties, WS, "}"), func(n Node) Node { + object = Map(And(WS, "{", WS, properties, WS, "}"), func(n interface{}) interface{} { ret := map[string]interface{}{} - for _, prop := range n.([]Node)[1].([]Node) { - vals := prop.([]Node) + for _, prop := range n.([]interface{})[1].([]interface{}) { + vals := prop.([]interface{}) if len(vals) == 3 { ret[vals[0].(string)] = vals[2] } else { @@ -28,20 +28,20 @@ var ( return ret }) - _null = Map(And(WS, "null"), func(n Node) Node { + _null = Map(And(WS, "null"), func(n interface{}) interface{} { return nil }) - _true = Map(And(WS, "true"), func(n Node) Node { + _true = Map(And(WS, "true"), func(n interface{}) interface{} { return true }) - _false = Map(And(WS, "false"), func(n Node) Node { + _false = Map(And(WS, "false"), func(n interface{}) interface{} { return false }) - Y = Map(And(&value, WS), func(n Node) Node { - nodes := n.([]Node) + Y = Map(And(&value, WS), func(n interface{}) interface{} { + nodes := n.([]interface{}) if len(nodes) > 0 { return nodes[0] } diff --git a/json/json_test.go b/json/json_test.go index 7f0ab9f..84fdd5c 100644 --- a/json/json_test.go +++ b/json/json_test.go @@ -1,10 +1,11 @@ package json import ( + stdlibJson "encoding/json" "testing" + parsecJson "github.com/prataprc/goparsec/json" "github.com/stretchr/testify/require" - . "github.com/vektah/goparsify" ) func TestUnmarshal(t *testing.T) { @@ -29,7 +30,7 @@ func TestUnmarshal(t *testing.T) { t.Run("array", func(t *testing.T) { result, err := Unmarshal(`[true, null, false]`) require.NoError(t, err) - require.Equal(t, []Node{true, nil, false}, result) + require.Equal(t, []interface{}{true, nil, false}, result) }) t.Run("object", func(t *testing.T) { @@ -41,16 +42,16 @@ func TestUnmarshal(t *testing.T) { const benchmarkString = `{"true":true, "false":false, "null": null}` -//func BenchmarkUnmarshalParsec(b *testing.B) { -// bytes := []byte(benchmarkString) -// -// for i := 0; i < b.N; i++ { -// scanner := parsecJson.NewJSONScanner(bytes) -// _, remaining := parsecJson.Y(scanner) -// -// require.True(b, remaining.Endof()) -// } -//} +func BenchmarkUnmarshalParsec(b *testing.B) { + bytes := []byte(benchmarkString) + + for i := 0; i < b.N; i++ { + scanner := parsecJson.NewJSONScanner(bytes) + _, remaining := parsecJson.Y(scanner) + + require.True(b, remaining.Endof()) + } +} func BenchmarkUnmarshalParsify(b *testing.B) { for i := 0; i < b.N; i++ { @@ -59,12 +60,11 @@ func BenchmarkUnmarshalParsify(b *testing.B) { } } -// -//func BenchmarkUnmarshalStdlib(b *testing.B) { -// bytes := []byte(benchmarkString) -// var result interface{} -// for i := 0; i < b.N; i++ { -// err := stdlibJson.Unmarshal(bytes, &result) -// require.NoError(b, err) -// } -//} +func BenchmarkUnmarshalStdlib(b *testing.B) { + bytes := []byte(benchmarkString) + var result interface{} + for i := 0; i < b.N; i++ { + err := stdlibJson.Unmarshal(bytes, &result) + require.NoError(b, err) + } +} diff --git a/json/profile/cpuprofile.bat b/json/profile/cpuprofile.bat index 2899eb3..c293b5e 100644 --- a/json/profile/cpuprofile.bat +++ b/json/profile/cpuprofile.bat @@ -1,3 +1,3 @@ go build profile.exe -cpuprofile cpu.out -go tool pprof --inuse_objects profile.exe cpu.out +go tool pprof profile.exe cpu.out diff --git a/json/profile/json.go b/json/profile/json.go index b94848b..a03d047 100644 --- a/json/profile/json.go +++ b/json/profile/json.go @@ -31,11 +31,13 @@ func main() { } }() } + max := 1000000 if *memprofile != "" { runtime.MemProfileRate = 1 + max = 10000 } - for i := 0; i < 10000; i++ { + for i := 0; i < max; i++ { _, err := json.Unmarshal(`{"true":true, "false":false, "null": null}`) if err != nil { panic(err) diff --git a/json/profile/memprofile.bat b/json/profile/memprofile.bat index a9c935e..71873ac 100644 --- a/json/profile/memprofile.bat +++ b/json/profile/memprofile.bat @@ -1,3 +1,3 @@ go build profile.exe -memprofile mem.out -go tool pprof --inuse_objects profile.exe mem.out +go tool pprof profile.exe mem.out |