1
0
mirror of https://github.com/golang/go synced 2024-11-26 20:41:24 -07:00

encoding/xml: use reflect.Value.Grow

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 <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Daniel Martí 2023-04-07 18:21:00 +01:00
parent 97df9c0b05
commit 10c079a0ad

View File

@ -284,7 +284,8 @@ func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
// Slice of element values. // Slice of element values.
// Grow slice. // Grow slice.
n := val.Len() 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. // Recur to read element into slice.
if err := d.unmarshalAttr(val.Index(n), attr); err != nil { 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. // Slice of element values.
// Grow slice. // Grow slice.
n := v.Len() 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. // Recur to read element into slice.
if err := d.unmarshal(v.Index(n), start, depth+1); err != nil { if err := d.unmarshal(v.Index(n), start, depth+1); err != nil {