【问题标题】:Pre-serializing some fields of a proto message预序列化 proto 消息的某些字段
【发布时间】:2017-11-17 22:19:11
【问题描述】:

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

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

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

当然,字典只构建一次,但运行时间的主要部分花费在为每个新节点一次又一次地序列化公共dictionary 部分时。

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

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

【问题讨论】:

    标签: c++ optimization serialization protocol-buffers


    【解决方案1】:

    Protobuf 的设计使得连接 === 组合,至少对于根消息。这意味着您可以使用 just 字典序列化对象,并在某处对字节进行快照。现在,对于每条真实消息,您可以粘贴该快照,然后使用 just 其他字段序列化一个对象 - 只需在之后直接敲击它:不需要额外的语法。这在语义上等同于同时序列化它们。事实上,由于它会保留字段顺序,它实际上也应该是相同的字节。

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

    【讨论】:

      【解决方案2】:

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

      1. 该字段必须是子消息,就像您的 TDictionary 一样。
      2. 有另一个外部消息的变体,用bytes 代替您要预序列化的子消息:
      消息 TMessage_preserialized { 可选字节字典 = 1; ... }
      1. 现在您可以单独序列化TDictionary 并将结果数据放入bytes 字段中。在 protobuf 格式中,子消息和bytes 字段的写出方式相同。这意味着您可以序列化为TMessage_preserialized,并且仍然可以正常反序列化TMessage

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-16
        相关资源
        最近更新 更多