2017-11-17 203 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