mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-03-08 19:14:05 +00:00
proto, internal/impl: avoid string->[]byte conversions
We trust the compiler to optimize away the string->[]byte conversion in code like: b = wire.AppendBytes(b, []byte(s)) In testing (go 1.12.5 linux/amd64), this optimization is not happening. Perhaps newer versions of the compiler will optimize this, but we shouldn't rely on it; avoid unnecessary conversions. Benchmark differences vs https://golang.org/cl/171462: name old time/op new time/op delta Wire/Marshal/google_message1_proto2-6 310ns ± 2% 189ns ± 3% -39.20% (p=0.000 n=8+8) Wire/Marshal/google_message1_proto3-6 389ns ± 8% 261ns ± 2% -33.03% (p=0.000 n=8+8) Wire/Marshal/google_message2-6 103µs ±11% 59µs ± 4% -42.17% (p=0.000 n=8+8) name old alloc/op new alloc/op delta Wire/Marshal/google_message1_proto2-6 592B ± 0% 240B ± 0% -59.46% (p=0.000 n=8+8) Wire/Marshal/google_message1_proto3-6 576B ± 0% 224B ± 0% -61.11% (p=0.000 n=8+8) Wire/Marshal/google_message2-6 196kB ± 0% 90kB ± 0% -54.05% (p=0.000 n=8+8) name old allocs/op new allocs/op delta Wire/Marshal/google_message1_proto2-6 5.00 ± 0% 1.00 ± 0% -80.00% (p=0.000 n=8+8) Wire/Marshal/google_message1_proto3-6 5.00 ± 0% 1.00 ± 0% -80.00% (p=0.000 n=8+8) Wire/Marshal/google_message2-6 1.66k ± 0% 0.00k ± 0% -99.94% (p=0.000 n=8+8) Change-Id: Idab7634b8c86604dffa46895ba2e61be38c9bd9c Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/183380 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
parent
8c86fc5e7d
commit
cedb595154
@ -43,8 +43,12 @@ wire.Size{{.WireType}}({{.FromGoType}})
|
||||
Append is a set of statements appending 'v' to 'b'.
|
||||
*/ -}}
|
||||
{{- define "Append" -}}
|
||||
{{- if eq .Name "String" -}}
|
||||
b = wire.AppendString(b, {{.FromGoType}})
|
||||
{{- else -}}
|
||||
b = wire.Append{{.WireType}}(b, {{.FromGoType}})
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range .}}
|
||||
{{- if .FromGoType }}
|
||||
|
@ -209,9 +209,9 @@ var ProtoKinds = []ProtoKind{
|
||||
Name: "String",
|
||||
WireType: WireBytes,
|
||||
ToValue: "string(v)",
|
||||
FromValue: "[]byte(v.String())",
|
||||
FromValue: "v.String()",
|
||||
GoType: GoString,
|
||||
FromGoType: "[]byte(v)",
|
||||
FromGoType: "v",
|
||||
},
|
||||
{
|
||||
Name: "Bytes",
|
||||
@ -344,8 +344,8 @@ func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescripto
|
||||
if fd.Syntax() == protoreflect.Proto3 && !utf8.ValidString(v.String()) {
|
||||
return b, errors.InvalidUTF8(string(fd.FullName()))
|
||||
}
|
||||
{{end -}}
|
||||
{{- if (eq .Name "Message") -}}
|
||||
b = wire.AppendString(b, {{.FromValue}})
|
||||
{{- else if (eq .Name "Message") -}}
|
||||
var pos int
|
||||
var err error
|
||||
b, pos = appendSpeculativeLength(b)
|
||||
|
@ -425,6 +425,11 @@ func AppendBytes(b []byte, v []byte) []byte {
|
||||
return append(AppendVarint(b, uint64(len(v))), v...)
|
||||
}
|
||||
|
||||
// AppendString appends v to b as a lenght-prefixed bytes value.
|
||||
func AppendString(b []byte, v string) []byte {
|
||||
return append(AppendVarint(b, uint64(len(v))), v...)
|
||||
}
|
||||
|
||||
// ConsumeBytes parses b as a length-prefixed bytes value, reporting its length.
|
||||
// This returns a negative length upon an error (see ParseError).
|
||||
func ConsumeBytes(b []byte) (v []byte, n int) {
|
||||
|
@ -412,7 +412,7 @@ var coderEnumSliceIface = ifaceCoderFuncs{
|
||||
func appendStringValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
v := *p.String()
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
if !utf8.ValidString(v) {
|
||||
return b, errInvalidUTF8{}
|
||||
}
|
||||
@ -430,7 +430,7 @@ func appendStringNoZeroValidateUTF8(b []byte, p pointer, wiretag uint64, _ marsh
|
||||
return b, nil
|
||||
}
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
if !utf8.ValidString(v) {
|
||||
return b, errInvalidUTF8{}
|
||||
}
|
||||
@ -445,7 +445,7 @@ var coderStringNoZeroValidateUTF8 = pointerCoderFuncs{
|
||||
func sizeStringSliceValidateUTF8(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
s := *p.StringSlice()
|
||||
for _, v := range s {
|
||||
size += tagsize + wire.SizeBytes(len([]byte(v)))
|
||||
size += tagsize + wire.SizeBytes(len(v))
|
||||
}
|
||||
return size
|
||||
}
|
||||
@ -455,7 +455,7 @@ func appendStringSliceValidateUTF8(b []byte, p pointer, wiretag uint64, _ marsha
|
||||
var err error
|
||||
for _, v := range s {
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
if !utf8.ValidString(v) {
|
||||
err = errInvalidUTF8{}
|
||||
}
|
||||
@ -470,13 +470,13 @@ var coderStringSliceValidateUTF8 = pointerCoderFuncs{
|
||||
|
||||
func sizeStringIfaceValidateUTF8(ival interface{}, tagsize int, _ marshalOptions) int {
|
||||
v := ival.(string)
|
||||
return tagsize + wire.SizeBytes(len([]byte(v)))
|
||||
return tagsize + wire.SizeBytes(len(v))
|
||||
}
|
||||
|
||||
func appendStringIfaceValidateUTF8(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
v := ival.(string)
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
if !utf8.ValidString(v) {
|
||||
return b, errInvalidUTF8{}
|
||||
}
|
||||
|
@ -2154,14 +2154,14 @@ var coderDoubleSliceIface = ifaceCoderFuncs{
|
||||
// sizeString returns the size of wire encoding a string pointer as a String.
|
||||
func sizeString(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
v := *p.String()
|
||||
return tagsize + wire.SizeBytes(len([]byte(v)))
|
||||
return tagsize + wire.SizeBytes(len(v))
|
||||
}
|
||||
|
||||
// appendString wire encodes a string pointer as a String.
|
||||
func appendString(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
v := *p.String()
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@ -2177,7 +2177,7 @@ func sizeStringNoZero(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
if len(v) == 0 {
|
||||
return 0
|
||||
}
|
||||
return tagsize + wire.SizeBytes(len([]byte(v)))
|
||||
return tagsize + wire.SizeBytes(len(v))
|
||||
}
|
||||
|
||||
// appendString wire encodes a string pointer as a String.
|
||||
@ -2188,7 +2188,7 @@ func appendStringNoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) (
|
||||
return b, nil
|
||||
}
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@ -2201,7 +2201,7 @@ var coderStringNoZero = pointerCoderFuncs{
|
||||
// It panics if the pointer is nil.
|
||||
func sizeStringPtr(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
v := **p.StringPtr()
|
||||
return tagsize + wire.SizeBytes(len([]byte(v)))
|
||||
return tagsize + wire.SizeBytes(len(v))
|
||||
}
|
||||
|
||||
// appendString wire encodes a *string pointer as a String.
|
||||
@ -2209,7 +2209,7 @@ func sizeStringPtr(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
func appendStringPtr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
v := **p.StringPtr()
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@ -2222,7 +2222,7 @@ var coderStringPtr = pointerCoderFuncs{
|
||||
func sizeStringSlice(p pointer, tagsize int, _ marshalOptions) (size int) {
|
||||
s := *p.StringSlice()
|
||||
for _, v := range s {
|
||||
size += tagsize + wire.SizeBytes(len([]byte(v)))
|
||||
size += tagsize + wire.SizeBytes(len(v))
|
||||
}
|
||||
return size
|
||||
}
|
||||
@ -2232,7 +2232,7 @@ func appendStringSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([
|
||||
s := *p.StringSlice()
|
||||
for _, v := range s {
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
@ -2245,14 +2245,14 @@ var coderStringSlice = pointerCoderFuncs{
|
||||
// sizeStringIface returns the size of wire encoding a string value as a String.
|
||||
func sizeStringIface(ival interface{}, tagsize int, _ marshalOptions) int {
|
||||
v := ival.(string)
|
||||
return tagsize + wire.SizeBytes(len([]byte(v)))
|
||||
return tagsize + wire.SizeBytes(len(v))
|
||||
}
|
||||
|
||||
// appendStringIface encodes a string value as a String.
|
||||
func appendStringIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
|
||||
v := ival.(string)
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@ -2265,7 +2265,7 @@ var coderStringIface = ifaceCoderFuncs{
|
||||
func sizeStringSliceIface(ival interface{}, tagsize int, _ marshalOptions) (size int) {
|
||||
s := *ival.(*[]string)
|
||||
for _, v := range s {
|
||||
size += tagsize + wire.SizeBytes(len([]byte(v)))
|
||||
size += tagsize + wire.SizeBytes(len(v))
|
||||
}
|
||||
return size
|
||||
}
|
||||
@ -2275,7 +2275,7 @@ func appendStringSliceIface(b []byte, ival interface{}, wiretag uint64, _ marsha
|
||||
s := *ival.(*[]string)
|
||||
for _, v := range s {
|
||||
b = wire.AppendVarint(b, wiretag)
|
||||
b = wire.AppendBytes(b, []byte(v))
|
||||
b = wire.AppendString(b, v)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ func (o MarshalOptions) marshalSingular(b []byte, fd protoreflect.FieldDescripto
|
||||
if fd.Syntax() == protoreflect.Proto3 && !utf8.ValidString(v.String()) {
|
||||
return b, errors.InvalidUTF8(string(fd.FullName()))
|
||||
}
|
||||
b = wire.AppendBytes(b, []byte(v.String()))
|
||||
b = wire.AppendString(b, v.String())
|
||||
case protoreflect.BytesKind:
|
||||
b = wire.AppendBytes(b, v.Bytes())
|
||||
case protoreflect.MessageKind:
|
||||
|
@ -42,7 +42,7 @@ func sizeSingular(num wire.Number, kind protoreflect.Kind, v protoreflect.Value)
|
||||
case protoreflect.DoubleKind:
|
||||
return wire.SizeFixed64()
|
||||
case protoreflect.StringKind:
|
||||
return wire.SizeBytes(len([]byte(v.String())))
|
||||
return wire.SizeBytes(len(v.String()))
|
||||
case protoreflect.BytesKind:
|
||||
return wire.SizeBytes(len(v.Bytes()))
|
||||
case protoreflect.MessageKind:
|
||||
|
Loading…
x
Reference in New Issue
Block a user