ApacheThriftとGoogleのProtocolBuffersの最大の長所と短所は何ですか?
15 に答える
どちらも同じ機能の多くを提供します。ただし、いくつかの違いがあります。
- Thriftは「例外」をサポートします
- プロトコルバッファには、はるかに優れたドキュメント/例があります
- スリフトにはビルトイン
Set
タイプがあります - プロトコルバッファは「拡張」を可能にします-外部コードが値を操作できるようにしながら、外部プロトコルを拡張してフィールドを追加することができます。Thriftでこれを行う方法はありません
- プロトコルバッファがはるかに読みやすいと思います
基本的に、それらはかなり同等です(私が読んだものよりもプロトコルバッファの方がわずかに効率的です)。
もう1つの重要な違いは、デフォルトでサポートされている言語です。
- プロトコルバッファ:Java、Android Java、C ++、Python、Ruby、C#、Go、Objective-C、Node.js
- Thrift:Java、C ++、Python、Ruby、C#、Go、Objective-C、JavaScript、Node.js、Erlang、PHP、Perl、Haskell、Smalltalk、OCaml、Delphi、D、Haxe
どちらも他のプラットフォームに拡張できますが、これらはすぐに使用できる言語バインディングです。
RPCはもう1つの重要な違いです。Thriftは、RPCクライアントとサーバーを実装するためのコードを生成します。ProtocolBuffersは、ほとんどの場合、データ交換形式としてのみ設計されているようです。
- Protobuf のシリアル化されたオブジェクトは、Thrift よりも約 30% 小さくなっています。
- オンにしない限り、protobuf オブジェクト (作成、シリアル化、逆シリアル化) で実行するほとんどのアクションは、thrift よりもはるかに遅くなり
option optimize_for = SPEED
ます。 - Thrift にはより豊富なデータ構造 (マップ、セット) があります
- Protobuf API はきれいに見えますが、生成されたクラスはすべて内部クラスとしてパックされており、あまり良くありません。
- Thrift 列挙型は実際の Java 列挙型ではありません。つまり、単なる int です。Protobuf には実際の Java 列挙型があります。
違いの詳細については、このオープン ソース プロジェクトでソース コードの差分を確認してください。
「Thrift vs Protocol buffers」のトピックで述べたように:
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 のインボックス サポート
- 他の言語 (Lua、Matlab、Ruby、Perl、R、Php、OCaml、Mercury、Erlang、Go、D、Lisp を含む) の Protobuf サポートは、サード パーティのアドオンとして利用できます(ところで、SWI-Prolog サポートはこちら)。
- Protobuf には、より優れたドキュメントと多くの例があります。
- Thriftには優れたチュートリアルが付属しています
- Protobuf オブジェクトが小さい
- 「optimize_for = SPEED」構成を使用すると、Protobuf が高速になります
- Thrift には RPC 実装が統合されていますが、Protobuf の RPC ソリューションは分離されていますが、利用可能です( Zeroc ICEなど)。
- Protobuf は BSD スタイルのライセンスでリリースされています
- Thrift は Apache 2 ライセンスの下でリリースされています
さらに、これらのソリューションに利用できる興味深い追加ツールがたくさんあり、それが決定する可能性があります. Protobuf の例を次に示します: Protobuf-wireshark、protobufeditor。
Protocol Buffersはよりコンパクトな表現になっているようですが、それはThriftホワイトペーパーを読んだことから得られる印象にすぎません。彼ら自身の言葉で:
コードを単純化して明確にするために、いくつかの極端なストレージの最適化(つまり、小さな整数をASCIIにパックするか、7ビットの継続形式を使用する)に反対することにしました。これらの変更は、それらを必要とするパフォーマンスが重要なユースケースに遭遇した場合に簡単に行うことができます。
また、それは私の印象かもしれませんが、ProtocolBuffersは構造体のバージョン管理に関してより厚い抽象化を持っているようです。Thriftにはバージョン管理のサポートがありますが、それを実現するには少し手間がかかります。
Pythonのprotobuffと比較して、テキストベースのプロトコルでより良いパフォーマンスを得ることができました。ただし、protobuffが提供するタイプチェックやその他の高度なutf8変換などはありません。
したがって、シリアル化/逆シリアル化だけが必要な場合は、おそらく他のものを使用できます。
http://dhruvbird.blogspot.com/2010/05/protocol-buffers-vs-http.html
まだ言及されていない明らかなことの 1 つは、長所と短所の両方になる可能性があることです (両方とも同じです)。それは、それらがバイナリ プロトコルであることです。これにより、よりコンパクトな表現が可能になり、パフォーマンスが向上する可能性がありますが (長所)、可読性 (またはデバッグ可能性) が低下するという短所があります。
また、どちらも xml (およびおそらく json) などの標準形式よりもツールのサポートが少し少なくなっています。
(編集)サイズとパフォーマンスの違いの両方に取り組み、他のいくつかの形式(xml、json)の数値も含む興味深い比較を次に示します。
ProtocolBuffers は高速です。
ここに素晴らしいベンチマークがあります:
http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking
Avro はさらに高速であるため、Avro を調べることもできます。
Microsoft はここにパッケージを持っています:
http://www.nuget.org/packages/Microsoft.Hadoop.Avro
ちなみに、私が今まで見た中で最も速いのはCap'nProtoです。
AC# の実装は、Marc Gravell の Github リポジトリにあります。
ウィキによると、Thrift ランタイムは Windows では動作しません。
これらのポイントのほとんどは、Thrift が RPC フレームワークであり、たまたまさまざまな方法 (バイナリ、XML など) を使用してデータをシリアル化する機能を備えているという基本的な事実を見落としていると思います。
Protocol Buffers は純粋にシリアル化のために設計されており、Thrift のようなフレームワークではありません。