【问题标题】:How does Google Protocol Buffers compare to ASN.1Google 协议缓冲区与 ASN.1 相比如何
【发布时间】:2009-02-27 15:43:32
【问题描述】:

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

【问题讨论】:

  • 也许是一个相关的问题:当我们已经拥有成熟的 ASN.1 时,为什么还需要协议缓冲区? Google 不是在这里发明的综合症?

标签: performance serialization protocol-buffers asn.1


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我已经很久没有做任何 ASN.1 工作了,但是大小很可能取决于您的类型和实际数据的详细信息。

    我会强烈建议您制作两者的原型并放入一些真实数据进行比较。

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

    【讨论】:

      【解决方案3】:

      当打包/编码消息的大小很重要时,您还应注意 protobuf 无法打包不属于 primitive numeric typeread thisrepeated 字段以获取更多信息。

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

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

      【讨论】:

        【解决方案4】:

        Protocol Buffers 不保证二进制编码中字段顺序的保留,但 ASN.1 可以。它与大小无关,因此在您的用例中可能不是最明显的,但对于比较、数字签名、简化解析以及可能的其他应用程序来说,它是一个重要的区别。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-18
          • 2016-12-19
          • 2010-11-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-08
          相关资源
          最近更新 更多