]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/gob: speedup decoding of maps by zeroing values
authorFilip Gruszczyński <gruszczy@gmail.com>
Fri, 31 Mar 2017 02:09:56 +0000 (19:09 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 26 May 2017 21:06:24 +0000 (21:06 +0000)
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>

src/encoding/gob/codec_test.go
src/encoding/gob/decode.go

index 387d58229c0ecfcaefe2f7dabb47bfb1f3fde617..eb9f306bcf5fcbf64a35e051e5261e6aad57ab2b 100644 (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},
index 879d6d2b77d1bf104336df85c7028416de7bec4a..8dece42e908b87b8ad014eede09b004aab3131ad 100644 (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)
        }
 }