2017-11-17 169 views
2

假设我有一个原始的结构,看起来像下面的一些字段:预序列化原消息

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

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

当然,字典只建立一次,但是它出现了,运行时间的主要部分花费在对每个新节点一次又一次序列化公共的dictionary部分。

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

我说对了,没有内置的方式来预先序列化消息字段而不破坏消息结构?这听起来像是一个理想的proto编译器插件。

回答

2

Protobuf被设计为使得连接===组合,至少对于根消息。这意味着您可以使用序列化对象,只需字典,并在某处快照字节。现在,对于每条真正的消息,您可以粘贴该快照,然后使用进行序列化,其他字段 - 只需将其直接敲入:无需额外的语法。这在语义上与在同一时间序列化它们完全相同。实际上,因为它将保留字段顺序,所以它实际上应该是相同的字节。

它可以帮助你在整个:)

2

马克的回答非常适合您的使用情况下使用“可选”。这里只是另一种选择:

  1. 该字段必须是一个子消息,就像你的TDictionary是。
  2. 具有外消息的另一变型中,与bytes代替子消息的要preserialize:
 
    message TMessage_preserialized { 
     optional bytes dictionary = 1; 
     ... 
    } 
  • 现在可以单独序列化TDictionary和放结果数据在bytes字段中。在protobuf格式中,submessages和bytes字段的写法相同。这意味着您可以序列化为TMessage_preserialized并仍然正常地反序列化为TMessage