预序列化原消息
问题描述:
假设我有一个原始的结构,看起来像下面的一些字段:预序列化原消息
message TMessage {
optional TDictionary dictionary = 1;
optional int specificField1 = 2;
optional TOtherMessage specificField2 = 3;
...
}
假设我使用C++。这是在主进程中使用网络将信息发送到一堆节点的消息存根。特别是,dictionary
字段对于所有的序列化消息是相当重的2)通用的,并且下面的所有特定字段都填充了目的节点特有的相对较小的信息。
当然,字典只建立一次,但是它出现了,运行时间的主要部分花费在对每个新节点一次又一次序列化公共的dictionary
部分。
明显的优化是预先将dictionary
序列化为字节字符串,并将其作为bytes
字段放入TMessage
,但这对我来说看起来有点令人讨厌。
我说对了,没有内置的方式来预先序列化消息字段而不破坏消息结构?这听起来像是一个理想的proto编译器插件。
答
Protobuf被设计为使得连接===组合,至少对于根消息。这意味着您可以使用序列化对象,只需字典,并在某处快照字节。现在,对于每条真正的消息,您可以粘贴该快照,然后使用对进行序列化,其他字段 - 只需将其直接敲入:无需额外的语法。这在语义上与在同一时间序列化它们完全相同。实际上,因为它将保留字段顺序,所以它实际上应该是相同的字节。
它可以帮助你在整个:)
答
马克的回答非常适合您的使用情况下使用“可选”。这里只是另一种选择:
- 该字段必须是一个子消息,就像你的
TDictionary
是。 - 具有外消息的另一变型中,与
bytes
代替子消息的要preserialize:
message TMessage_preserialized { optional bytes dictionary = 1; ... }
- 现在可以单独序列化
TDictionary
和放结果数据在bytes
字段中。在protobuf格式中,submessages和bytes
字段的写法相同。这意味着您可以序列化为TMessage_preserialized
并仍然正常地反序列化为TMessage
。