各种protobuf实现之间的差异

sum*_*dds 3 protocol-buffers

每种实现的权衡,优缺点是什么?他们有什么不同吗?我想要实现的是将一个盒子的矢量存储到一个protobuf中.

Impl 1:

package foo;

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

  repeated Box boxes = 1; 
}
Run Code Online (Sandbox Code Playgroud)

Impl 2:

package foo;

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

message Boxes 
{ repeated Box boxes = 1; 
}
Run Code Online (Sandbox Code Playgroud)

Impl 3:将这些消息的多个流式传输到同一个文件中.

package foo;

message Box 
{ required int32 w = 1;
  required int32 h = 2;
}
Run Code Online (Sandbox Code Playgroud)

Bru*_*tin 7

Marc Gravell的答案肯定是正确的,但他错过了一点

  • 选项1和2(重复选项)将立即对所有框进行序列化/反序列化
  • 选项3(文件中的多条消息)将逐框序列化/反序列化.如果使用java,则可以使用分隔文件(这将在消息的开头添加Var-Int长度).

大多数情况下,使用重复或多个消息无关紧要,但如果有数百万/百亿的盒子,内存将成为选项1和2(重复)和选项3(文件中的多个消息)的问题将是最好的选择.

总结如下:

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

我个人希望看到"标准"多消息格式


Mar*_*ell 6

1和2仅更改声明类型的位置/方式.工作本身也是一样的.

3更有意思:你不能只是BoxBox之后流Box,因为protobuf中的根对象没有终止(允许concat === merge).如果您编写Boxes,那么当您反序列化时,您将只有一个Box与最后一个w并且h已写入.你需要添加一个长度前缀; 你可以任意做,但是:如果你碰巧选择"varint" - 编码长度,你就接近repeated给你的东西 - 除了repeated还包括一个字段标题(字段1,类型2 - 所以二进制1010 =十进制10)每个"varint"长度之前.

如果我是你,我只是repeated为了简单而使用.您选择的1/2中的哪一个取决于个人选择.