aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/xml/read.go
diff options
context:
space:
mode:
authorapocelipes <seve3r@outlook.com>2025-09-24 03:23:03 +0000
committerGopher Robot <gobot@golang.org>2025-09-29 07:53:08 -0700
commitd42d56b764f4c8b06aaa2de2dc9c1d2171e79490 (patch)
treee98e91eea146b520559b05466405e50755c2f753 /src/encoding/xml/read.go
parent6d51f932575284d6e78baa5e98f47f737a9f5b19 (diff)
downloadgo-d42d56b764f4c8b06aaa2de2dc9c1d2171e79490.tar.xz
encoding/xml: make use of reflect.TypeAssert
To make the code more readable and improve performance: goos: darwin goarch: arm64 pkg: encoding/xml cpu: Apple M4 │ old │ new │ │ sec/op │ sec/op vs base │ Marshal-10 1.902µ ± 1% 1.496µ ± 1% -21.37% (p=0.000 n=10) Unmarshal-10 3.877µ ± 1% 3.418µ ± 2% -11.84% (p=0.000 n=10) HTMLAutoClose-10 1.314µ ± 3% 1.333µ ± 1% ~ (p=0.270 n=10) geomean 2.132µ 1.896µ -11.07% │ old │ new │ │ B/op │ B/op vs base │ Marshal-10 5.570Ki ± 0% 5.570Ki ± 0% ~ (p=1.000 n=10) ¹ Unmarshal-10 7.586Ki ± 0% 7.555Ki ± 0% -0.41% (p=0.000 n=10) HTMLAutoClose-10 3.496Ki ± 0% 3.496Ki ± 0% ~ (p=1.000 n=10) ¹ geomean 5.286Ki 5.279Ki -0.14% ¹ all samples are equal │ old │ new │ │ allocs/op │ allocs/op vs base │ Marshal-10 23.00 ± 0% 23.00 ± 0% ~ (p=1.000 n=10) ¹ Unmarshal-10 185.0 ± 0% 184.0 ± 0% -0.54% (p=0.000 n=10) HTMLAutoClose-10 93.00 ± 0% 93.00 ± 0% ~ (p=1.000 n=10) ¹ geomean 73.42 73.28 -0.18% ¹ all samples are equal Updates #62121 Change-Id: Ie458e7458d4358c380374571d380ca3b65ca87bb GitHub-Last-Rev: bb6bb3039328ca1d53ee3d56fd6597109ed76b09 GitHub-Pull-Request: golang/go#75483 Reviewed-on: https://go-review.googlesource.com/c/go/+/704215 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Carlos Amedee <carlos@golang.org>
Diffstat (limited to 'src/encoding/xml/read.go')
-rw-r--r--src/encoding/xml/read.go77
1 files changed, 46 insertions, 31 deletions
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
index af25c20f06..d3cb74b2c4 100644
--- a/src/encoding/xml/read.go
+++ b/src/encoding/xml/read.go
@@ -255,28 +255,36 @@ func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
}
val = val.Elem()
}
- if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) {
+ if val.CanInterface() {
// This is an unmarshaler with a non-pointer receiver,
// so it's likely to be incorrect, but we do what we're told.
- return val.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr)
+ if unmarshaler, ok := reflect.TypeAssert[UnmarshalerAttr](val); ok {
+ return unmarshaler.UnmarshalXMLAttr(attr)
+ }
}
if val.CanAddr() {
pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(unmarshalerAttrType) {
- return pv.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr)
+ if pv.CanInterface() {
+ if unmarshaler, ok := reflect.TypeAssert[UnmarshalerAttr](pv); ok {
+ return unmarshaler.UnmarshalXMLAttr(attr)
+ }
}
}
// Not an UnmarshalerAttr; try encoding.TextUnmarshaler.
- if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
+ if val.CanInterface() {
// This is an unmarshaler with a non-pointer receiver,
// so it's likely to be incorrect, but we do what we're told.
- return val.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value))
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](val); ok {
+ return textUnmarshaler.UnmarshalText([]byte(attr.Value))
+ }
}
if val.CanAddr() {
pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- return pv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value))
+ if pv.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](pv); ok {
+ return textUnmarshaler.UnmarshalText([]byte(attr.Value))
+ }
}
}
@@ -303,12 +311,7 @@ func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
return copyValue(val, []byte(attr.Value))
}
-var (
- attrType = reflect.TypeFor[Attr]()
- unmarshalerType = reflect.TypeFor[Unmarshaler]()
- unmarshalerAttrType = reflect.TypeFor[UnmarshalerAttr]()
- textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]()
-)
+var attrType = reflect.TypeFor[Attr]()
const (
maxUnmarshalDepth = 10000
@@ -352,27 +355,35 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) e
val = val.Elem()
}
- if val.CanInterface() && val.Type().Implements(unmarshalerType) {
+ if val.CanInterface() {
// This is an unmarshaler with a non-pointer receiver,
// so it's likely to be incorrect, but we do what we're told.
- return d.unmarshalInterface(val.Interface().(Unmarshaler), start)
+ if unmarshaler, ok := reflect.TypeAssert[Unmarshaler](val); ok {
+ return d.unmarshalInterface(unmarshaler, start)
+ }
}
if val.CanAddr() {
pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(unmarshalerType) {
- return d.unmarshalInterface(pv.Interface().(Unmarshaler), start)
+ if pv.CanInterface() {
+ if unmarshaler, ok := reflect.TypeAssert[Unmarshaler](pv); ok {
+ return d.unmarshalInterface(unmarshaler, start)
+ }
}
}
- if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
- return d.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler))
+ if val.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](val); ok {
+ return d.unmarshalTextInterface(textUnmarshaler)
+ }
}
if val.CanAddr() {
pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- return d.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler))
+ if pv.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](pv); ok {
+ return d.unmarshalTextInterface(textUnmarshaler)
+ }
}
}
@@ -453,7 +464,7 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) e
return UnmarshalError(e)
}
fv := finfo.value(sv, initNilPointers)
- if _, ok := fv.Interface().(Name); ok {
+ if _, ok := reflect.TypeAssert[Name](fv); ok {
fv.Set(reflect.ValueOf(start.Name))
}
}
@@ -578,20 +589,24 @@ Loop:
}
}
- if saveData.IsValid() && saveData.CanInterface() && saveData.Type().Implements(textUnmarshalerType) {
- if err := saveData.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil {
- return err
+ if saveData.IsValid() && saveData.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](saveData); ok {
+ if err := textUnmarshaler.UnmarshalText(data); err != nil {
+ return err
+ }
+ saveData = reflect.Value{}
}
- saveData = reflect.Value{}
}
if saveData.IsValid() && saveData.CanAddr() {
pv := saveData.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- if err := pv.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil {
- return err
+ if pv.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](pv); ok {
+ if err := textUnmarshaler.UnmarshalText(data); err != nil {
+ return err
+ }
+ saveData = reflect.Value{}
}
- saveData = reflect.Value{}
}
}