当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《Google协议缓冲区与ASN.1相比如何?》经验,为你挑选了3个好方法。

Google Protocol Buffers和ASN.1(使用PER编码)之间最明显的区别是什么?对于我的项目,最重要的问题是序列化数据的大小.有没有人在两者之间做过任何数据大小的比较?



1> 小智..:

如果使用带有未对齐PER的ASN.1,并使用适当的约束定义数据类型(例如,指定整数的上限/上限,列表长度的上限等),则编码将非常紧凑.对于诸如字段之间的对齐或填充之类的事物将不会浪费比特,并且每个字段将被编码为保持其允许的值范围所需的最小比特数.例如,INTEGER(1..8)类型的字段将以3位编码(1 ='000',2 ='001',...,8 ='111'); 具有四个备选方案的CHOICE将占用2位(表示所选择的备选方案)加上所选备选方案占用的位.ASN.1还有许多其他有趣的功能,已成功用于许多已发布的标准中.一个示例是扩展标记("..."),当应用于SEQUENCE,CHOICE,ENUMERATED和其他类型时,可以实现实现规范的不同版本的端点之间的向后兼容性.



2> Jon Skeet..:

自从我完成任何ASN.1工作以来已经很长时间了,但是这个大小很可能取决于你的类型和实际数据的细节.

强烈建议您将两者都原型化并将一些真实数据放入比较中.

如果您的协议缓冲区包含重复的原始类型,您应该查看Subversion for Protocol Buffers中的最新源 - 它们现在可以以"压缩"格式表示,这样节省空间更多.(我的C#端口刚刚赶上了这个功能,上周某个时候.)



3> georg..:

当打包/编码后的消息的大小很重要时,您还应该注意protobuf无法打包非repeated字段的事实primitive numeric type,请阅读以获取更多信息。

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

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

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有