关于序列化:节俭与协议缓冲区的最大区别是什么?

关于序列化:节俭与协议缓冲区的最大区别是什么?

Biggest differences of Thrift vs Protocol Buffers?

Apache Thrift与Google的协议缓冲区最大的优缺点是什么?


它们都提供许多相同的功能。但是,有一些区别:

  • Thrift支持"例外"
  • 协议缓冲区具有更好的文档/示例
  • 节俭具有内置的Set类型
  • 协议缓冲区允许"扩展"-您可以扩展外部协议以添加额外的字段,同时仍然允许外部代码对值进行操作。 Thrift中无法做到这一点
  • 我发现协议缓冲区更容易阅读

基本上,它们是相当等效的(与我所阅读的协议缓冲区相比,其效率稍高一些)。


另一个重要区别是默认支持的语言。

  • 协议缓冲区:Java,Android Java,C ++,Python,Ruby,C#,Go,Objective-C,Node.js
  • 节俭:Java,C ++,Python,Ruby,C#,Go,Objective-C,JavaScript,Node.js,Erlang,PHP,Perl,Haskell,Smalltalk,OCaml,Delphi,D,Haxe

两者都可以扩展到其他平台,但是这些是现成可用的语言绑定。


RPC是另一个主要区别。 Thrift生成代码以实现RPC客户端和服务器,在这些客户端和服务器中,协议缓冲区似乎大多仅设计为数据交换格式。


  • Protobuf序列化的对象比Thrift小约30%。
  • 除非打开option optimize_for = SPEED,否则您可能希望对protobuf对象执行的大多数操作(创建,序列化,反序列化)比节俭要慢得多。
  • Thrift具有更丰富的数据结构(Map,Set)
  • Protobuf API看起来更干净,尽管生成的类都打包为内部类,这不太好。
  • 节俭枚举不是真正的Java枚举,即它们只是整数。 Protobuf具有真正的Java枚举。

要进一步了解差异,请查看此开源项目中的源代码差异。


正如我所说的"节制与协议缓冲区"主题:

参考Thrift,Protobuf和JSON比较:

  • Thrift支持开箱即用的AS3,C ++,C#,D,Delphi,Go,Graphviz,Haxe,Haskell,Java,Javascript,Node.js,OCaml,Smalltalk,Typescript,Perl,PHP,Python,Ruby,...
  • C ++,Python,Java-Protobuf中的内置支持
  • Protobuf对其他语言(包括Lua,Matlab,Ruby,Perl,R,Php,OCaml,Mercury,Erlang,Go,D,Lisp)的支持可作为第三方插件(btw。这是SWI-Prolog支持)提供。
  • Protobuf有更好的文档和大量示例。
  • 节俭带有一个很好的教程
  • Protobuf对象较小
  • 取消使用" optimize_for = SPEED"时,Protobuf更快
  • Thrift具有集成的RPC实现,而对于Protobuf而言,RPC解决方案是分离的,但是可以使用(例如Zeroc ICE)。
  • Protobuf是根据BSD样式许可发布的
  • Thrift是根据Apache 2许可发行的

此外,对于这些解决方案,还有很多有趣的其他工具可供使用,这些工??具可能会决定。以下是Protobuf的示例:Protobuf-wireshark,protobufeditor。


与基于python的probbuff相比,基于文本的协议我可以获得更好的性能。但是,没有protobuff提供的类型检查或其他精美的utf8转换等。

因此,如果只需要序列化/反序列化,则可以使用其他方法。

http://dhruvbird.blogspot.com/2010/05/protocol-buffers-vs-http.html


协议缓冲区似乎具有更紧凑的表示形式,但这只是我从Thrift白皮书中获得的印象。用他们自己的话说:

We decided against some extreme storage optimizations (i.e. packing
small integers into ASCII or using a 7-bit continuation format)
for the sake of simplicity and clarity in the code. These alterations
can easily be made if and when we encounter a performance-critical
use case that demands them.

同样,这可能只是我的印象,但是协议缓冲区似乎在结构版本控制方面有更粗略的抽象。 Thrift确实有一些版本控制支持,但是要实现它需要一些努力。


尚未提及的一件显而易见的事情是,它们既可以是优点,也可以是缺点(并且两者都相同)是它们是二进制协议。这允许更紧凑的表示形式,并可能有更多的性能(优点),但可读性(或更确切地说,可调试性)降低,这是一个缺点。

而且,两者都比xml(甚至json)等标准格式的工具支持少。

(编辑)这是一个有趣的比较,它解决了大小和性能上的差异,并且还包括其他一些格式(xml,json)的数字。


ProtocolBuffers更快。
这里有一个不错的基准:
http://code.google.com/p/thrift-protobuf-compare/wiki/基准测试

您可能还需要研究Avro,因为Avro甚至更快。
Microsoft在这里有一个软件包:
http://www.nuget.org/packages/Microsoft.Hadoop.Avro

顺便说一句,我见过最快的是Cap'nProto;
可以在Marc Gravell的Github存储库中找到C#实现。


并且根据Wiki,Thrift运行时不能在Windows上运行。


首先,protobuf并不是完整的RPC实现。它需要类似gRPC的东西。

与Thrift相比,gPRC非常慢:

http://szelei.me/rpc-benchmark-part1/


我认为这些观点中的大多数都错过了Thrift是RPC框架这一基本事实,该框架恰好具有使用多种方法(二进制,XML等)对数据进行序列化的能力。

协议缓冲区纯粹是为序列化而设计的,它不是像Thrift这样的框架。


还需要注意的是,并非所有受支持的语言都能与节俭或protobuf保持一致。在这一点上,除了基础的序列化之外,还取决于模块的实现。请注意检查计划使用的任何语言的基准。


这里有一些要点,我还要补充一点,以防有人穿过这里。

Thrift为您提供了在Thrift-binary和Thrift-compact(反)串行化器之间进行选择的选项,Thrift-binary将具有出色的性能,但包大小更大,而Thrift-compact将为您提供良好的压缩效果,但需要更多的处理能力。这很方便,因为您始终可以像更改代码行一样容易地在这两种模式之间切换(麻烦,甚至使其可配置)。因此,如果您不确定应针对数据包大小或处理能力对应用程序进行多少优化,节俭可能是一个有趣的选择。

PS:参见thekvs的出色基准测试项目,该项目比较了许多序列化程序,包括thrift-binary,thrift-compact和protobuf:https://github.com/thekvs/cpp-serializers

PS:还有一个名为YAS的序列化器,它也提供了此选项,但是它没有模式,请参见上面的链接。


推荐阅读