Protocol buffers protobuf中流消息实现的比较
在对多个相同类型的消息进行编码的情况下,每种流媒体实现的优缺点是什么 他们有什么不同吗?我想要实现的是将一个盒子的向量存储到protobuf中 Impl 1: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
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)写在一起。它们将自动合并,当你阅读时,它们都将是一个大的重复字段。