]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/gob: optimize decoding of slice
authorkorzhao <korzhao95@gmail.com>
Fri, 3 Sep 2021 07:55:16 +0000 (15:55 +0800)
committerIan Lance Taylor <iant@golang.org>
Tue, 7 Sep 2021 21:39:06 +0000 (21:39 +0000)
In CL 345572, we used the reflect.Value.SetLen method to avoid
extra memory allocation for reflect.Value.Slice.
This also applies to function decodeSlice

name                   old time/op    new time/op    delta
DecodeStringsSlice-12    96.5µs ±12%    63.0µs ± 8%  -34.68%  (p=0.000 n=9+10)

name                   old alloc/op   new alloc/op   delta
DecodeStringsSlice-12    89.3kB ± 0%    65.3kB ± 0%  -26.89%  (p=0.000 n=10+10)

name                   old allocs/op  new allocs/op  delta
DecodeStringsSlice-12     3.18k ± 0%     2.18k ± 0%  -31.47%  (p=0.000 n=10+10)

Change-Id: Ifdb43716cc90a265962dec022704a5571f447fd8
Reviewed-on: https://go-review.googlesource.com/c/go/+/347533
Reviewed-by: Joe Tsai <joetsai@digital-static.net>
Reviewed-by: Rob Pike <r@golang.org>
Trust: Joe Tsai <joetsai@digital-static.net>
Run-TryBot: Joe Tsai <joetsai@digital-static.net>
TryBot-Result: Go Bot <gobot@golang.org>

src/encoding/gob/decode.go
src/encoding/gob/timing_test.go

index 4ef9ef7243ed578dff70f241626b58c606a420bf..f92556f8ab691f31e05bb01d15e2d6b1ed81eb7e 100644 (file)
@@ -625,7 +625,7 @@ func (dec *Decoder) decodeSlice(state *decoderState, value reflect.Value, elemOp
        if value.Cap() < n {
                value.Set(reflect.MakeSlice(typ, n, n))
        } else {
-               value.Set(value.Slice(0, n))
+               value.SetLen(n)
        }
        dec.decodeArrayHelper(state, value, elemOp, n, ovfl, helper)
 }
index ceb21c4107b0a8b3e4b69982b06b3c139ea28b5a..516aeea92c606f4eeef9dd2006bf874516737e2a 100644 (file)
@@ -279,7 +279,13 @@ func BenchmarkDecodeStringSlice(b *testing.B) {
        }
        benchmarkDecodeSlice(b, a)
 }
-
+func BenchmarkDecodeStringsSlice(b *testing.B) {
+       a := make([][]string, 1000)
+       for i := range a {
+               a[i] = []string{"now is the time"}
+       }
+       benchmarkDecodeSlice(b, a)
+}
 func BenchmarkDecodeBytesSlice(b *testing.B) {
        a := make([][]byte, 1000)
        for i := range a {