From 10c079a0ad2283be3761a47eda6e41bde38fd16b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Mart=C3=AD?= Date: Fri, 7 Apr 2023 18:21:00 +0100 Subject: [PATCH] encoding/xml: use reflect.Value.Grow MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Like https://go.dev/cl/481376 did for encoding/gob, but now for encoding/xml, which had very similar code. One minor difference is that encoding/xml now needs a SetLen before the call to Index, as otherwise we index just past the length. Still, calling Grow and SetLen is easier to understand, and avoids needing to make a new zero value. goos: linux goarch: amd64 pkg: encoding/xml cpu: AMD Ryzen 7 PRO 5850U with Radeon Graphics │ old │ new │ │ sec/op │ sec/op vs base │ Unmarshal-8 6.904µ ± 1% 6.980µ ± 1% +1.10% (p=0.009 n=6) │ old │ new │ │ B/op │ B/op vs base │ Unmarshal-8 7.656Ki ± 0% 7.586Ki ± 0% -0.92% (p=0.002 n=6) │ old │ new │ │ allocs/op │ allocs/op vs base │ Unmarshal-8 188.0 ± 0% 185.0 ± 0% -1.60% (p=0.002 n=6) Change-Id: Id83feb467a9c59c80c7936aa892780aae7e8b809 Reviewed-on: https://go-review.googlesource.com/c/go/+/483135 TryBot-Result: Gopher Robot Reviewed-by: Michael Knyszek Run-TryBot: Daniel Martí Reviewed-by: Ian Lance Taylor --- src/encoding/xml/read.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go index 43be08eeef..c1c843e4c0 100644 --- a/src/encoding/xml/read.go +++ b/src/encoding/xml/read.go @@ -284,7 +284,8 @@ func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error { // Slice of element values. // Grow slice. n := val.Len() - val.Set(reflect.Append(val, reflect.Zero(val.Type().Elem()))) + val.Grow(1) + val.SetLen(n + 1) // Recur to read element into slice. if err := d.unmarshalAttr(val.Index(n), attr); err != nil { @@ -410,7 +411,8 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) e // Slice of element values. // Grow slice. n := v.Len() - v.Set(reflect.Append(val, reflect.Zero(v.Type().Elem()))) + v.Grow(1) + v.SetLen(n + 1) // Recur to read element into slice. if err := d.unmarshal(v.Index(n), start, depth+1); err != nil { -- 2.48.1