1 回答
TA贡献1802条经验 获得超5个赞
您只需使用经常重复的字段定义一个新消息,并将其用作其他消息中的字段类型:
message Metadata {
uint64 id = 1;
google.protobuf.Timestamp createdAt = 2;
google.protobuf.Timestamp updatedAt = 3;
}
message League {
Metadata metadata = 1;
string name = 2;
//...
}
在 Go 中,您将该字段初始化为普通结构(包选择器将取决于您如何从 protobuffers 实际生成 Go 类型):Metadata
func newLeague() *grpcgen.League {
return &grpcgen.League{
Metadata: &grpcgen.Metadata{
Id: 1000,
CreatedAt: ptypes.TimestampProto(time.Now()),
UpdatedAt: ptypes.TimestampProto(time.Now()),
}
Name: "foo",
//...
}
}
编辑:
你认为这会减慢编码/解码过程吗?
我们可以运行以下基准测试:
package foo
import (
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"foo/grpcgen"
"testing"
)
var withmeta = &grpcgen.LeagueWithMeta{
Metadata: &grpcgen.Metadata{
Id: 1000,
CreatedAt: ptypes.TimestampNow(),
UpdatedAt: ptypes.TimestampNow(),
},
Name: "foo",
}
var nometa = &grpcgen.LeagueNoMeta{
Id: 1000,
CreatedAt: ptypes.TimestampNow(),
UpdatedAt: ptypes.TimestampNow(),
Name: "foo",
}
func BenchmarkEncProto(b *testing.B) {
b.Run("encode with meta", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
b, _ := proto.Marshal(withmeta)
if b == nil {
panic("not marshaled")
}
}
})
b.Run("encode without meta", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
b, _ := proto.Marshal(nometa)
if b == nil {
panic("not marshaled")
}
}
})
}
$ go test -bench=. ./proto_benchmark_test.go -benchtime=10s
goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i7-7660U CPU @ 2.50GHz
BenchmarkEncProto/encode_with_meta-4 13124650 948.8 ns/op 96 B/op 4 allocs/op
BenchmarkEncProto/encode_without_meta-4 25832161 417.0 ns/op 64 B/op 2 allocs/op
PASS
ok command-line-arguments 24.629s
不包装消息中的字段具有更好的性能,这并不奇怪。在实践中,这不会以可观的方式影响您的程序。Metadata
- 1 回答
- 0 关注
- 71 浏览
添加回答
举报