Protocol buffers protobuf中流消息实现的比较

Protocol buffers protobuf中流消息实现的比较,protocol-buffers,Protocol Buffers,在对多个相同类型的消息进行编码的情况下,每种流媒体实现的优缺点是什么 他们有什么不同吗?我想要实现的是将一个盒子的向量存储到protobuf中 Impl 1: package foo; message Boxes { message Box { required int32 w = 1; required int32 h = 2; } repeated Box boxes = 1; } package foo; message Box { required

在对多个相同类型的消息进行编码的情况下,每种流媒体实现的优缺点是什么

他们有什么不同吗?我想要实现的是将一个盒子的向量存储到protobuf中

Impl 1:

package foo;

message Boxes
{ 
  message Box 
  { required int32 w = 1;
    required int32 h = 2;
  }

  repeated Box boxes = 1; 
}
package foo;

message Box 
{ required int32 w = 1;
  required int32 h = 2;
}

message Boxes 
{ repeated Box boxes = 1; 
}
Impl 2:

package foo;

message Boxes
{ 
  message Box 
  { required int32 w = 1;
    required int32 h = 2;
  }

  repeated Box boxes = 1; 
}
package foo;

message Box 
{ required int32 w = 1;
  required int32 h = 2;
}

message Boxes 
{ repeated Box boxes = 1; 
}
Impl 3:将这些消息中的多条流式传输到同一个文件中

package foo;

message Box 
{ required int32 w = 1;
  required int32 h = 2;
}

1和2仅更改类型声明的位置/方式。作品本身将是相同的

3更有趣:您不能在
Box
之后流式传输
Box
,因为protobuf中的根对象没有终止(以允许concat==merge)。如果您只写
Box
es,当您反序列化时,您将有一个
Box
,其中包含最后写入的
w
h
。您需要添加长度前缀;您可以任意这样做,但是:如果您碰巧选择“varint”(可变长度)编码,则与
repeated
提供的内容非常接近-除了
repeated
在每个“varint”长度之前还包括一个字段头(字段1,类型2-因此二进制1010=十进制10)


如果我是你,为了简单起见,我会重复使用
。你选择1/2中的哪一个取决于个人选择

Marc Gravell的回答当然是正确的,但他遗漏了一点

  • 选项的1和2(重复选项)将同时序列化/反序列化所有框
  • 选项3(文件中的多条消息)将逐框序列化/反序列化。 如果使用java,则可以使用分隔文件(这将在消息开头添加一个Var Int length)
大多数情况下,无论您使用的是重复消息还是多条消息,都无关紧要,但如果有数百万或数十亿个盒子,则选项1和2(重复)的内存将是一个问题,而选项3(文件中的多条消息)将是最佳选择

总而言之:

  • 如果有数百万/数十亿个盒子,请使用-选项3(文件中有多条消息)
  • 否则,请使用其中一个重复选项(1/2),因为它更简单,并且在所有协议缓冲区版本中都受支持

就我个人而言,我希望看到一种“标准”的多消息格式

OK,这很有意义。我在3中的意思是通过包含长度参数(我从您的另一个答案和protobuf文档中了解到)来流式传输。这就是说,添加长度的流媒体和默认的“重复”流媒体之间的差异使我的理解更加清晰。W.r.t 1和2,这些选择有什么分歧吗?还有一点,选项1和2会一次序列化/反序列化所有框,而选项3会逐个框序列化/反序列化。如果您谈论的是数百万或数十亿个盒子,那么选项3可能更可取(需要的内存要少得多)。不确定您使用的是哪种语言,但Java实现了一个带分隔符的消息(支持选项3)。@BruceMartin您应该在回答中添加这一点:“可以在没有任何分隔符的情况下,将一堆消息(1/2)写在一起。它们将自动合并,当你阅读时,它们都将是一个大的重复字段。