mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-02-11 06:40:37 +00:00
internal/impl: pass ExtensionTypeDescriptor to extensionMap
The layers freely convert between ExtensionTypeDescriptor (via ExtensionTypeDescriptor.Type) and ExtensionType (via ExtensionType.TypeDescriptor()). For certain hot functions , like (*extensionMap).Has() and (*extensionMap).Get(), this saves a Type() and TypeDescriptor() pair. Oddly, the gains are bigger than I expected. This commit is 02-typedesciptor-not-type, it is layered on top of CL 576315 (named 01-cse-hasextension): benchstat 00-cse-messageinfo 01-cse-hasextension 02-typedesciptor-not-type goarch: amd64 cpu: AMD Ryzen Threadripper PRO 3995WX 64-Cores │ 00-cse-messageinfo │ 01-cse-hasextension │ 02-typedesciptor-not-type │ │ sec/op │ sec/op vs base │ sec/op vs base │ Extension/Has/None-12 103.30n ± 3% 96.73n ± 1% -6.36% (p=0.000 n=10) 85.54n ± 2% -17.19% (p=0.000 n=10) Extension/Has/Set-12 113.05n ± 3% 107.15n ± 1% -5.22% (p=0.000 n=10) 97.36n ± 2% -13.88% (p=0.000 n=10) Extension/Get/None-12 182.7n ± 2% 176.3n ± 2% -3.48% (p=0.000 n=10) 173.3n ± 2% -5.09% (p=0.000 n=10) Extension/Get/Set-12 140.1n ± 2% 138.0n ± 1% -1.46% (p=0.024 n=10) 135.0n ± 1% -3.64% (p=0.000 n=10) Extension/Set-12 218.6n ± 2% 219.5n ± 1% ~ (p=0.172 n=10) 210.2n ± 2% -3.82% (p=0.001 n=10) geomean 145.6n 140.8n -3.25% 132.6n -8.91% Change-Id: If9c67c680ca57b5d93f863bb1c72f3e5031ed18c Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/576316 Reviewed-by: Michael Stapelberg <stapelberg@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Nicolas Hillegeer <aktau@google.com>
This commit is contained in:
parent
39bbf13930
commit
98873a2050
@ -783,55 +783,55 @@ func (m *{{.}}) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) b
|
||||
func (m *{{.}}) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.has(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Has(xt)
|
||||
return mi.extensionMap(m.pointer()).Has(xd)
|
||||
}
|
||||
}
|
||||
func (m *{{.}}) Clear(fd protoreflect.FieldDescriptor) {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
fi.clear(m.pointer())
|
||||
} else {
|
||||
mi.extensionMap(m.pointer()).Clear(xt)
|
||||
mi.extensionMap(m.pointer()).Clear(xd)
|
||||
}
|
||||
}
|
||||
func (m *{{.}}) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.get(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Get(xt)
|
||||
return mi.extensionMap(m.pointer()).Get(xd)
|
||||
}
|
||||
}
|
||||
func (m *{{.}}) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
fi.set(m.pointer(), v)
|
||||
} else {
|
||||
mi.extensionMap(m.pointer()).Set(xt, v)
|
||||
mi.extensionMap(m.pointer()).Set(xd, v)
|
||||
}
|
||||
}
|
||||
func (m *{{.}}) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.mutable(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Mutable(xt)
|
||||
return mi.extensionMap(m.pointer()).Mutable(xd)
|
||||
}
|
||||
}
|
||||
func (m *{{.}}) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.newField()
|
||||
} else {
|
||||
return xt.New()
|
||||
return xd.Type().New()
|
||||
}
|
||||
}
|
||||
func (m *{{.}}) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
|
||||
|
@ -247,11 +247,10 @@ func (m *extensionMap) Range(f func(protoreflect.FieldDescriptor, protoreflect.V
|
||||
}
|
||||
}
|
||||
}
|
||||
func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) {
|
||||
func (m *extensionMap) Has(xd protoreflect.ExtensionTypeDescriptor) (ok bool) {
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
xd := xt.TypeDescriptor()
|
||||
x, ok := (*m)[int32(xd.Number())]
|
||||
if !ok {
|
||||
return false
|
||||
@ -264,20 +263,19 @@ func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) {
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (m *extensionMap) Clear(xt protoreflect.ExtensionType) {
|
||||
delete(*m, int32(xt.TypeDescriptor().Number()))
|
||||
func (m *extensionMap) Clear(xd protoreflect.ExtensionTypeDescriptor) {
|
||||
delete(*m, int32(xd.Number()))
|
||||
}
|
||||
func (m *extensionMap) Get(xt protoreflect.ExtensionType) protoreflect.Value {
|
||||
xd := xt.TypeDescriptor()
|
||||
func (m *extensionMap) Get(xd protoreflect.ExtensionTypeDescriptor) protoreflect.Value {
|
||||
if m != nil {
|
||||
if x, ok := (*m)[int32(xd.Number())]; ok {
|
||||
return x.Value()
|
||||
}
|
||||
}
|
||||
return xt.Zero()
|
||||
return xd.Type().Zero()
|
||||
}
|
||||
func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) {
|
||||
xd := xt.TypeDescriptor()
|
||||
func (m *extensionMap) Set(xd protoreflect.ExtensionTypeDescriptor, v protoreflect.Value) {
|
||||
xt := xd.Type()
|
||||
isValid := true
|
||||
switch {
|
||||
case !xt.IsValidValue(v):
|
||||
@ -290,7 +288,7 @@ func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value)
|
||||
isValid = v.Message().IsValid()
|
||||
}
|
||||
if !isValid {
|
||||
panic(fmt.Sprintf("%v: assigning invalid value", xt.TypeDescriptor().FullName()))
|
||||
panic(fmt.Sprintf("%v: assigning invalid value", xd.FullName()))
|
||||
}
|
||||
|
||||
if *m == nil {
|
||||
@ -300,16 +298,15 @@ func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value)
|
||||
x.Set(xt, v)
|
||||
(*m)[int32(xd.Number())] = x
|
||||
}
|
||||
func (m *extensionMap) Mutable(xt protoreflect.ExtensionType) protoreflect.Value {
|
||||
xd := xt.TypeDescriptor()
|
||||
func (m *extensionMap) Mutable(xd protoreflect.ExtensionTypeDescriptor) protoreflect.Value {
|
||||
if xd.Kind() != protoreflect.MessageKind && xd.Kind() != protoreflect.GroupKind && !xd.IsList() && !xd.IsMap() {
|
||||
panic("invalid Mutable on field with non-composite type")
|
||||
}
|
||||
if x, ok := (*m)[int32(xd.Number())]; ok {
|
||||
return x.Value()
|
||||
}
|
||||
v := xt.New()
|
||||
m.Set(xt, v)
|
||||
v := xd.Type().New()
|
||||
m.Set(xd, v)
|
||||
return v
|
||||
}
|
||||
|
||||
@ -426,7 +423,7 @@ func (m *messageIfaceWrapper) protoUnwrap() interface{} {
|
||||
|
||||
// checkField verifies that the provided field descriptor is valid.
|
||||
// Exactly one of the returned values is populated.
|
||||
func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionType) {
|
||||
func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionTypeDescriptor) {
|
||||
var fi *fieldInfo
|
||||
if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) {
|
||||
fi = mi.denseFields[n]
|
||||
@ -455,7 +452,7 @@ func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo,
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName()))
|
||||
}
|
||||
return nil, xtd.Type()
|
||||
return nil, xtd
|
||||
}
|
||||
panic(fmt.Sprintf("field %v is invalid", fd.FullName()))
|
||||
}
|
||||
|
@ -66,55 +66,55 @@ func (m *messageState) Range(f func(protoreflect.FieldDescriptor, protoreflect.V
|
||||
func (m *messageState) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.has(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Has(xt)
|
||||
return mi.extensionMap(m.pointer()).Has(xd)
|
||||
}
|
||||
}
|
||||
func (m *messageState) Clear(fd protoreflect.FieldDescriptor) {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
fi.clear(m.pointer())
|
||||
} else {
|
||||
mi.extensionMap(m.pointer()).Clear(xt)
|
||||
mi.extensionMap(m.pointer()).Clear(xd)
|
||||
}
|
||||
}
|
||||
func (m *messageState) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.get(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Get(xt)
|
||||
return mi.extensionMap(m.pointer()).Get(xd)
|
||||
}
|
||||
}
|
||||
func (m *messageState) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
fi.set(m.pointer(), v)
|
||||
} else {
|
||||
mi.extensionMap(m.pointer()).Set(xt, v)
|
||||
mi.extensionMap(m.pointer()).Set(xd, v)
|
||||
}
|
||||
}
|
||||
func (m *messageState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.mutable(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Mutable(xt)
|
||||
return mi.extensionMap(m.pointer()).Mutable(xd)
|
||||
}
|
||||
}
|
||||
func (m *messageState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.newField()
|
||||
} else {
|
||||
return xt.New()
|
||||
return xd.Type().New()
|
||||
}
|
||||
}
|
||||
func (m *messageState) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
|
||||
@ -197,55 +197,55 @@ func (m *messageReflectWrapper) Range(f func(protoreflect.FieldDescriptor, proto
|
||||
func (m *messageReflectWrapper) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.has(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Has(xt)
|
||||
return mi.extensionMap(m.pointer()).Has(xd)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) Clear(fd protoreflect.FieldDescriptor) {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
fi.clear(m.pointer())
|
||||
} else {
|
||||
mi.extensionMap(m.pointer()).Clear(xt)
|
||||
mi.extensionMap(m.pointer()).Clear(xd)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.get(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Get(xt)
|
||||
return mi.extensionMap(m.pointer()).Get(xd)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
fi.set(m.pointer(), v)
|
||||
} else {
|
||||
mi.extensionMap(m.pointer()).Set(xt, v)
|
||||
mi.extensionMap(m.pointer()).Set(xd, v)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.mutable(m.pointer())
|
||||
} else {
|
||||
return mi.extensionMap(m.pointer()).Mutable(xt)
|
||||
return mi.extensionMap(m.pointer()).Mutable(xd)
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
|
||||
mi := m.messageInfo()
|
||||
mi.init()
|
||||
if fi, xt := mi.checkField(fd); fi != nil {
|
||||
if fi, xd := mi.checkField(fd); fi != nil {
|
||||
return fi.newField()
|
||||
} else {
|
||||
return xt.New()
|
||||
return xd.Type().New()
|
||||
}
|
||||
}
|
||||
func (m *messageReflectWrapper) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
|
||||
|
Loading…
x
Reference in New Issue
Block a user