预序列化原型消息的某些字段

Pre-serializing some fields of a proto message

本文关键字:字段 消息 序列化 原型      更新时间:2023-10-16

假设我有一个原型结构,如下所示:

message TMessage {
optional TDictionary dictionary = 1;
optional int specificField1 = 2;
optional TOtherMessage specificField2 = 3;
...
}

假设我正在使用C++。这是主进程中使用的消息存根,用于使用网络向节点群发送信息。特别地,dictionary字段1)非常重2)对于所有序列化的消息都是通用的,并且下面的所有特定字段都填充了目标节点特有的相对较小的信息。

当然,dictionary只构建了一次,但它的大部分运行时间都花在了为每个新节点一次又一次地序列化公共dictionary部分上。

明显的优化是将dictionary预序列化到字节字符串中,并将其作为bytes字段放入TMessage中,但这对我来说有点讨厌

我说得对吗?没有内置的方法可以在不破坏消息结构的情况下预序列化消息字段?这听起来像是为proto编译器开发一个好插件的想法。

Protobuf的设计使得串联===组合,至少对于根消息是这样。这意味着您可以用字典序列化一个对象,并在某个地方快照字节。现在,对于每一条真实的消息,您都可以粘贴该快照,然后用的其他字段序列化一个对象——只需在之后直接删除它:不需要额外的语法。这在语义上等同于同时序列化它们。事实上,由于它将保留字段顺序,因此它实际上也应该是相同的字节。

这有助于您在整个过程中使用"可选":)

Marc的答案非常适合您的用例。这里只是另一个选择:

  1. 字段必须是子消息,就像TDictionary一样
  2. 使用外部消息的另一个变体,用bytes代替要保存的子消息:
消息TMessage_preseialized{可选字节字典=1;。。。}
  1. 现在您可以单独序列化TDictionary,并将生成的数据放入bytes字段。在protobuf格式中,子消息和bytes字段以相同的方式编写。这意味着您可以序列化为TMessage_preserialized,但仍可以反序列化为普通的TMessage