From: Rick Arnold Date: Thu, 31 Jan 2013 01:53:48 +0000 (-0800) Subject: encoding/json: improve performance of Unmarshal on primitive types X-Git-Tag: go1.1rc2~1226 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=eea0f19990c2bcb2a5f92e60307428fc7e18e153;p=gostls13.git encoding/json: improve performance of Unmarshal on primitive types Attempt 2. The first fix was much faster but ignored syntax errors. benchmark old ns/op new ns/op delta BenchmarkCodeEncoder 74993543 72982390 -2.68% BenchmarkCodeMarshal 77811181 75610637 -2.83% BenchmarkCodeDecoder 213337123 190144982 -10.87% BenchmarkCodeUnmarshal 212180972 190394852 -10.27% BenchmarkCodeUnmarshalReuse 202113428 182106660 -9.90% BenchmarkUnmarshalString 1343 919 -31.57% BenchmarkUnmarshalFloat64 1149 908 -20.97% BenchmarkUnmarshalInt64 967 778 -19.54% BenchmarkSkipValue 28851581 28414125 -1.52% benchmark old MB/s new MB/s speedup BenchmarkCodeEncoder 25.88 26.59 1.03x BenchmarkCodeMarshal 24.94 25.66 1.03x BenchmarkCodeDecoder 9.10 10.21 1.12x BenchmarkCodeUnmarshal 9.15 10.19 1.11x BenchmarkSkipValue 69.05 70.11 1.02x Fixes #3949. R=rsc CC=golang-dev https://golang.org/cl/7231058 --- diff --git a/src/pkg/encoding/json/decode.go b/src/pkg/encoding/json/decode.go index e6e15b00d6..6109450221 100644 --- a/src/pkg/encoding/json/decode.go +++ b/src/pkg/encoding/json/decode.go @@ -52,16 +52,34 @@ import ( // an UnmarshalTypeError describing the earliest such error. // func Unmarshal(data []byte, v interface{}) error { - d := new(decodeState).init(data) // Quick check for well-formedness. // Avoids filling out half a data structure // before discovering a JSON syntax error. + var d decodeState err := checkValid(data, &d.scan) if err != nil { return err } + // skip heavy processing for primitive values + var first byte + var i int + for i, first = range data { + if first > ' ' || !isSpace(rune(first)) { + break + } + } + if first != '{' && first != '[' { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + return &InvalidUnmarshalError{reflect.TypeOf(v)} + } + d.literalStore(data[i:], rv.Elem(), false) + return d.savedError + } + + d.init(data) return d.unmarshal(v) }