协议缓冲区与JSON或BSON的比较

96

有人了解Protocol Buffers相对于BSON(二进制JSON)或一般JSON的性能特点吗?

  • 数据传输大小
  • 序列化速度
  • 反序列化速度

这些似乎是在HTTP上传输的好的二进制协议。我只是想知道,在C#环境中,哪种协议从长远来看会更好。

下面是我在BSONProtocol Buffers上阅读到的信息。


有人认为(我认为其中包括前Protocol Buffers作者)使用一个更大但序列化成本更低的格式,然后使用快速标准压缩器压缩输出是一个更好的想法。 - CodesInChaos
http://devblog.corditestudios.com/blog/2012/10/29/bson-vs-yaml-vs-protobuf/ - laike9m
我认为在问题本身提出某种比较方法之前,不应该重新开放此问题(否则这将导致过于主观的讨论/范围过大)。 - YakovL
也许更多地涉及到每种格式的优缺点,答案可能包括一个决策树。 - Technophile
4个回答

77

20
这个回答不包含有关协议缓冲区的信息。 - Victor Yarema

67

Thrift是另一种类似于 Protocol Buffers 的选择。

Java 社区有很好的基准测试,可以比较这些技术的序列化/反序列化和线路大小:https://github.com/eishay/jvm-serializers/wiki

通常情况下,JSON 在线路大小上略大,DeSer 稍差;但是它在普及性和能够不需要源 IDL 轻松解释的能力方面胜出。最后一点是Apache Avro正在努力解决的问题,且在性能方面超过了两者。

Microsoft 发布了一个 C# NuGet 包Microsoft.Hadoop.Avro


1
小的消息大小并不自动转化为快速性能,请参阅此文章http://soa.sys-con.com/node/250512。 - vtd-xml-author
1
好的链接;唯一让我不确定的是关于Avro的评论--虽然它在其核心用例(大量相似数据条目)上可以更高效地工作,但在这个基准测试中(测试处理单个请求),它似乎表现不太快。 - StaxMan
CoDec,MoDem... 我更喜欢“SeDes” :) - nawfal

56

以下是一些最近的基准测试结果,展示了流行的.NET序列化器的性能。

Burning Monks 基准测试 展示了序列化简单 POCO 的性能,而综合的 Northwind 基准测试 展示了序列化 Microsoft Northwind 数据集中每个表格的行的组合结果。

enter image description here

基本上,协议缓冲区 (protobuf-net) 比.NET中最快的基类库 Serializer (XML DataContractSerializer) 快7倍。它也比竞争对手更小,因为它还比Microsoft最紧凑的序列化格式(JsonDataContractSerializer) 小2.2倍

ServiceStack的文本序列化器与二进制protobuf-net的性能最接近,其中它的Json序列化器仅比protobuf-net慢2.58倍


1
很棒的文章 - 但如果可能的话,当展示平均值时,你应该总是在条形图上加上误差线。 - jtromans

25

Protocol Buffers旨在用于数据传输:

  1. 非常小的消息大小 - 其中一方面是使用高效的变长整数表示。
  2. 非常快速的解码 - 它是一种二进制协议。
  3. protobuf为编码和解码消息生成超级高效的C++代码 -- 提示:如果将所有变长整数或静态大小的项编码到其中,则它将以确定性速度进行编码和解码。
  4. 它提供了一个非常丰富的数据模型 -- 可以高效地编码非常复杂的数据结构。

JSON只是文本格式,需要进行解析。提示:在JSON中编码“十亿”个整数将需要相当多的字符:Billion = 12个字符(长标度),但在二进制格式下可以适配于uint32_t中。现在如果尝试编码一个double呢?那将会更加糟糕。


4
然而,它有一个相当不幸的缺点,即不能处理继承。虽然组合是一种有效的替代方法,但我不想被我的数据传输对象强制使用组合而非继承。 - Barracoder
4
我认为扩展可以以非常类似于继承的方式使用... https://developers.google.com/protocol-buffers/docs/reference/cpp-generated#extension - kralyk
1
是的,扩展是一个非常好的点。我每天在工作中都用到它。 - Yngve Sneen Lindal
协议缓冲区是为了传输而设计的。“the wire”指的是计算机网络的物理层和数据链路层,它们负责将数据从一个设备传输到另一个设备。 - Marcos Pereira
@marcospgp,“the wire” 意思就是网络。但是现在我们使用如此多的无线网络,这听起来可能有些奇怪。 - Victor Yarema
@MarcosPereira 想象一下通过电线(或同轴电缆、双绞线、光纤等)传输的数据流。 - Technophile

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接