1
0
mirror of https://github.com/golang/go synced 2024-11-18 01:54:45 -07:00

encoding/gob: speedup decoding of maps by zeroing values

Instead of allocating a new reflect.Value object on every loop we zero it.

DecodeComplex128Slice-8  13.1µs ± 7%  13.2µs ± 8%     ~     (p=0.347 n=18+19)
DecodeFloat64Slice-8     8.13µs ± 5%  8.00µs ± 3%     ~     (p=0.168 n=20+19)
DecodeInt32Slice-8       8.27µs ± 5%  8.08µs ± 5%   -2.27%  (p=0.001 n=19+18)
DecodeStringSlice-8      17.9µs ±12%  17.8µs ±11%     ~     (p=0.989 n=20+19)
DecodeInterfaceSlice-8    163µs ±10%   159µs ± 4%     ~     (p=0.057 n=19+19)
DecodeMap-8               220µs ± 2%   183µs ± 1%  -17.07%  (p=0.000 n=19+18)

Updates #19525

Change-Id: I27f8edd4761787f6b9928d34cefa08a34a6e25b2
Reviewed-on: https://go-review.googlesource.com/39203
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Filip Gruszczyński 2017-03-30 19:09:56 -07:00 committed by Ian Lance Taylor
parent 2cb3d1d893
commit 11ab865d6f
2 changed files with 33 additions and 4 deletions

View File

@ -548,12 +548,14 @@ func TestEndToEnd(t *testing.T) {
X float64
Z *int
}
s1 := "string1"
s2 := "string2"
type T1 struct {
A, B, C int
M map[string]*float64
M2 map[int]T3
Mstring map[string]string
Mintptr map[int]*int
Mcomp map[complex128]complex128
Marr map[[2]string][2]*float64
EmptyMap map[string]int // to check that we receive a non-nil map.
N *[3]float64
Strs *[2]string
@ -565,14 +567,35 @@ func TestEndToEnd(t *testing.T) {
}
pi := 3.14159
e := 2.71828
two := 2.0
meaning := 42
fingers := 5
s1 := "string1"
s2 := "string2"
var comp1 complex128 = complex(1.0, 1.0)
var comp2 complex128 = complex(1.0, 1.0)
var arr1 [2]string
arr1[0] = s1
arr1[1] = s2
var arr2 [2]string
arr2[0] = s2
arr2[1] = s1
var floatArr1 [2]*float64
floatArr1[0] = &pi
floatArr1[1] = &e
var floatArr2 [2]*float64
floatArr2[0] = &e
floatArr2[1] = &two
t1 := &T1{
A: 17,
B: 18,
C: -5,
M: map[string]*float64{"pi": &pi, "e": &e},
M2: map[int]T3{4: T3{X: pi, Z: &meaning}, 10: T3{X: e, Z: &fingers}},
Mstring: map[string]string{"pi": "3.14", "e": "2.71"},
Mintptr: map[int]*int{meaning: &fingers, fingers: &meaning},
Mcomp: map[complex128]complex128{comp1: comp2, comp2: comp1},
Marr: map[[2]string][2]*float64{arr1: floatArr1, arr2: floatArr2},
EmptyMap: make(map[string]int),
N: &[3]float64{1.5, 2.5, 3.5},
Strs: &[2]string{s1, s2},

View File

@ -565,10 +565,16 @@ func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value refl
elemIsPtr := mtyp.Elem().Kind() == reflect.Ptr
keyInstr := &decInstr{keyOp, 0, nil, ovfl}
elemInstr := &decInstr{elemOp, 0, nil, ovfl}
keyP := reflect.New(mtyp.Key())
keyZ := reflect.Zero(mtyp.Key())
elemP := reflect.New(mtyp.Elem())
elemZ := reflect.Zero(mtyp.Elem())
for i := 0; i < n; i++ {
key := decodeIntoValue(state, keyOp, keyIsPtr, allocValue(mtyp.Key()), keyInstr)
elem := decodeIntoValue(state, elemOp, elemIsPtr, allocValue(mtyp.Elem()), elemInstr)
key := decodeIntoValue(state, keyOp, keyIsPtr, keyP.Elem(), keyInstr)
elem := decodeIntoValue(state, elemOp, elemIsPtr, elemP.Elem(), elemInstr)
value.SetMapIndex(key, elem)
keyP.Elem().Set(keyZ)
elemP.Elem().Set(elemZ)
}
}