谷歌协议缓冲区(Google Protocol Buffers)和ASN.1(具有PER编码)最显着的区别是什么?对于我的项目来说,最重要的问题是序列化数据的大小。是否有人在这两者之间进行过数据大小比较?
谷歌协议缓冲区(Google Protocol Buffers)和ASN.1(具有PER编码)最显着的区别是什么?对于我的项目来说,最重要的问题是序列化数据的大小。是否有人在这两者之间进行过数据大小比较?
如果你使用ASN.1和Unaligned PER,并使用适当的约束定义你的数据类型(例如,为整数指定下限/上限,在列表长度上指定上限等),那么你的编码将非常紧凑。不会浪费任何比特用于字段之间的对齐或填充,每个字段将使用最少量的位来表示其允许的值范围。例如,INTEGER类型的字段(1..8)将使用3位进行编码(1='000',2='001',...,8='111');而具有四种选择项的CHOICE将占用2位(指示所选选项)加上所选选项占用的位数。 ASN.1还具有许多其他有趣的功能,已成功地用于许多发布的标准中。例如,扩展标记(“...”),当应用于SEQUENCE、CHOICE、ENUMERATED和其他类型时,可以在实现不同版本规范的端点之间实现向前和向后兼容性。
我很久没做ASN.1相关的工作了,但是大小可能非常依赖于您类型和实际数据的细节。
我极力建议您对两者进行原型设计,并放入一些真实数据来进行比较。
如果您的协议缓冲区包含重复的原始类型,您应该查看Protocol Buffers Subversion中的最新源代码 - 现在它们可以以更加空间高效的“打包”格式表示。(我的C#端口刚刚在上周实现了此功能。)
原始数字类型
的重复字段
,有关更多信息,请阅读此处。message P{
required sint32 x = 1; // -0x1ffff to 0x20000
required sint32 y = 2; // -0x1ffff to 0x20000
required sint32 z = 3; // -0x319c to 0x3200
}
message Array{
repeated P ps = 1;
optional uint32 somemoredata = 2;
}
message Ps{
repeated sint32 xs = 1 [packed=true];
repeated sint32 ys = 2 [packed=true];
repeated sint32 zs = 3 [packed=true];
}
message Array{
required Ps ps = 1;
optional uint32 somemoredata = 2;
}
这会导致消息大小大约在100字节(所有值为零),300字节(范围最大值处的值)和500字节(所有值为高32位值)之间。
Protocol Buffers(协议缓冲区)不能保证二进制编码中字段的顺序,但是ASN.1可以。尽管在您的使用情况下可能并不容易注意到,但它是比较、数字签名、简化解析和可能其他应用程序的重要区别。