【问题标题】:gogo/protobuf avoid allocating new objects for repeated fieldgogo/protobuf 避免为重复字段分配新对象
【发布时间】:2023-02-02 14:25:56
【问题描述】:

考虑一个简单的 protobuf 文件:

syntax = "proto3";
package tutorial;

import "github.com/gogo/protobuf@v1.3.2/gogoproto/gogo.proto";

message Point {
  uint32 timestamp = 1;
  double value = 2;
}

message Metric {
  string metric = 1;
  repeated Point points = 2 [(gogoproto.nullable) = false];
}

我已经使用 https://github.com/gogo/protobuf 将原型编译为 Go

gogoproto.nullable 帮助生成 Point 切片作为非指针(指针将使垃圾收集器工作更多):

type Metric struct {
    Metric               string   `protobuf:"bytes,1,opt,name=metric,proto3" json:"metric,omitempty"`
    Points               []Point  `protobuf:"bytes,2,rep,name=points,proto3" json:"points"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

然而,生成的Unmarshal 函数一直在分配新对象并附加到切片中。

m.Points = append(m.Points, Point{})

这些小的分配很重并且会影响性​​能。我想重用相同的内存并避免一起分配,也许使用固定长度的数组?这可以做到吗?如何做到?

【问题讨论】:

  • 请指定最少可执行的示例。 “相同的记忆”是什么意思?和什么一样?

标签: go protocol-buffers protoc


【解决方案1】:
m.Points = append(m.Points, Point{})

此代码中没有堆分配(假设m.Points 有足够的容量)。 Point{} 在堆栈上分配一个对象,并按值将其复制到切片中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 2015-07-30
    • 2016-04-17
    • 2014-10-25
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多