Commit 29264c6f authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

json: use strconv.Append variants to avoid allocations in encoding

Before/after, best of 3:
json.BenchmarkCodeEncoder  10  183495300 ns/op  10.58 MB/s
->
json.BenchmarkCodeEncoder  10  133025100 ns/op  14.59 MB/s

But don't get too excited about this.  These benchmarks, while
stable at any point of time, fluctuate wildly with any line of
code added or removed anywhere in the path due to stack splitting
issues.

It's currently much faster, though, and this is the API that
doesn't allocate so should always be faster in theory.

R=golang-dev, dsymonds, rsc, r, gri
CC=golang-dev
https://golang.org/cl/5411052
parent 143f3b38
......@@ -197,6 +197,7 @@ var hex = "0123456789abcdef"
// An encodeState encodes JSON into a bytes.Buffer.
type encodeState struct {
bytes.Buffer // accumulated output
scratch [64]byte
}
func (e *encodeState) marshal(v interface{}) (err error) {
......@@ -275,14 +276,26 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
writeString(e, strconv.FormatInt(v.Int(), 10))
b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
if quoted {
writeString(e, string(b))
} else {
e.Write(b)
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
writeString(e, strconv.FormatUint(v.Uint(), 10))
b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
if quoted {
writeString(e, string(b))
} else {
e.Write(b)
}
case reflect.Float32, reflect.Float64:
writeString(e, strconv.FormatFloat(v.Float(), 'g', -1, v.Type().Bits()))
b := strconv.AppendFloat(e.scratch[:0], v.Float(), 'g', -1, v.Type().Bits())
if quoted {
writeString(e, string(b))
} else {
e.Write(b)
}
case reflect.String:
if quoted {
sb, err := Marshal(v.String())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment