Google协议缓冲区与ASN.1相比如何

问题描述 投票:32回答:4

Google协议缓冲区和ASN.1(具有PER编码)之间最明显的区别是什么?对于我的项目,最重要的问题是序列化数据的大小。有没有人做过两者之间的数据大小比较?

performance serialization protocol-buffers asn.1
4个回答
11
投票

距离我完成ASN.1的工作已经很长时间了,但是大小很可能取决于类型和实际数据的详细信息。

[我会[[强烈建议您将两者都原型化并放入一些实际数据进行比较。

如果协议缓冲区将包含重复的原始类型,则应查看Subversion中协议缓冲区的最新来源-它们现在可以以“打包”格式表示,这样可以节省更多空间。 (我的C#端口已经在上周的某个时间

just

赶上了此功能。)

24
投票
如果您将ASN.1与未对齐的PER一起使用,并使用适当的约束来定义数据类型(例如,为整数指定上下限,为列表长度指定上限等),则您的编码将非常紧凑。不会在字段之间浪费任何位,例如对齐或填充,并且每个字段将以保持其允许的值范围所需的最小位数进行编码。例如,类型为INTEGER(1..8)的字段将被编码为3位(1 ='000',2 ='001',...,8 ='111');带有四个选项的CHOICE将占据2位(指示所选的选项)加上所选的选项所占据的位。 ASN.1具有许多其他有趣的功能,这些功能已经在许多已发布的标准中成功使用。一个示例是扩展标记(“ ...”),将其应用于SEQUENCE,CHOICE,ENUMERATED和其他类型时,可实现实现不同版本规范的端点之间的向后和向前兼容性。

5
投票
[打包/编码后的消息的大小很重要时,您还应该注意,protobuf无法打包不是repeatedprimitive numeric typeread this字段,以获取更多信息。

这是一个问题,例如如果您有以下类型的消息:(注释定义了实际值的范围)

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; }

[如果您的数组长度为例如32,则将导致带有protobuf的打包消息大小约为250到450字节,这取决于数组实际包含的值。如果您使用完整的32位范围

或,如果使用int32而不是sint32并且具有负值,则甚至可以增加到1000字节以上。

原始数据Blob(假设z可以定义为int16值)将仅消耗320字节,因此

ASN.1

消息总是小于320字节,因为最大值是实际上不是32位,而是19位(x,y)和15位(z)。protobuf消息的大小可以使用以下消息定义进行优化:

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位高值)之间。

0
投票
协议缓冲区不能保证以二进制编码形式保留字段顺序,但是ASN.1可以。它与大小无关,因此在您的用例中可能不是最引人注意的,但是对于比较,数字签名,简化的解析以及可能的其他应用而言,这是一个重要的区别。
© www.soinside.com 2019 - 2024. All rights reserved.