From f62c9701b4bc61da6a5f4db8ef81d816f112430e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Mart=C3=AD?= Date: Sat, 1 Apr 2023 18:55:06 +0100 Subject: [PATCH] encoding/gob: use reflect.Value.Grow MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Growing by one is a simpler, and often cheaper, operation compared to appending one (newly created) zero value. The method was introduced in Go 1.20. growSlice in dec_helpers.go is left alone, as it grows using the builtin append instead of reflect.Append. No noticeable performance difference on any of our benchmarks, as this code only runs for slices large enough to not fit in saferio.SliceCap, and none of our benchmarks use data that large. goos: linux goarch: amd64 pkg: encoding/gob cpu: AMD Ryzen 7 PRO 5850U with Radeon Graphics │ old │ new │ │ sec/op │ sec/op vs base │ DecodeBytesSlice-8 11.37µ ± 1% 11.46µ ± 4% ~ (p=0.315 n=10) DecodeInterfaceSlice-8 96.49µ ± 1% 95.75µ ± 1% ~ (p=0.436 n=10) geomean 33.12µ 33.12µ +0.01% │ old │ new │ │ B/op │ B/op vs base │ DecodeBytesSlice-8 22.39Ki ± 0% 22.39Ki ± 0% ~ (p=1.000 n=10) DecodeInterfaceSlice-8 80.25Ki ± 0% 80.25Ki ± 0% ~ (p=0.650 n=10) geomean 42.39Ki 42.39Ki +0.00% │ old │ new │ │ allocs/op │ allocs/op vs base │ DecodeBytesSlice-8 169.0 ± 0% 169.0 ± 0% ~ (p=1.000 n=10) ¹ DecodeInterfaceSlice-8 3.178k ± 0% 3.178k ± 0% ~ (p=1.000 n=10) ¹ geomean 732.9 732.9 +0.00% Change-Id: I468aebf4ae6f197a1fd35f6fee809ca591c1788f Reviewed-on: https://go-review.googlesource.com/c/go/+/481376 Reviewed-by: Ian Lance Taylor Run-TryBot: Daniel Martí TryBot-Result: Gopher Robot Reviewed-by: Rob Pike Reviewed-by: Michael Knyszek --- src/encoding/gob/decode.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/encoding/gob/decode.go b/src/encoding/gob/decode.go index bffe45a72a..76ea332e5d 100644 --- a/src/encoding/gob/decode.go +++ b/src/encoding/gob/decode.go @@ -381,10 +381,10 @@ func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) { if i >= ln { // We didn't allocate the entire slice, // due to using saferio.SliceCap. - // Append a value to grow the slice. + // Grow the slice for one more element. // The slice is full, so this should // bump up the capacity. - value.Set(reflect.Append(value, reflect.Zero(value.Type().Elem()))) + value.Grow(1) } // Copy into s up to the capacity or n, // whichever is less. @@ -549,8 +549,8 @@ func (dec *Decoder) decodeArrayHelper(state *decoderState, value reflect.Value, } if i >= ln { // This is a slice that we only partially allocated. - // Grow it using append, up to length. - value.Set(reflect.Append(value, reflect.Zero(value.Type().Elem()))) + // Grow it up to length. + value.Grow(1) cp := value.Cap() if cp > length { cp = length -- 2.50.0