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:
parent
2cb3d1d893
commit
11ab865d6f
@ -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},
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user