プロトコル バッファと Java のネイティブ シリアライゼーションの速度を比較したことはありませんが、相互運用性に関しては、Java のネイティブ シリアライゼーションは絶対にダメです。また、ほとんどの場合、スペースの点でプロトコル バッファーほど効率的ではありません。もちろん、保存できるものや参照などに関しては、多少柔軟性があります。Protocol Buffers は、意図されたものに非常に優れており、ニーズに合っている場合は素晴らしいですが、相互運用性のために明らかな制限があります。 (と他のこと)。
私は最近、Java と .NET の Protocol Buffers ベンチマーク フレームワークを投稿しました。Java バージョンはメインの Google プロジェクト( benchmarks ディレクトリ内) にあり、.NET バージョンは私の C# ポート プロジェクトにあります。PB 速度と Java シリアライゼーション速度を比較したい場合は、同様のクラスを作成してベンチマークすることができます。ただし、相互運用性に関心がある場合は、ネイティブ Java シリアル化 (または .NET ネイティブ バイナリ シリアル化) について考え直すつもりはありません。
Protocol Buffers 以外にも、相互運用可能なシリアライゼーションのオプションがあります。Thrift、JSON、およびYAMLが思い浮かびます。
編集: さて、相互運用性はそれほど重要ではないので、シリアル化フレームワークから必要なさまざまな品質をリストしてみる価値があります。考慮すべきことの 1 つはバージョン管理です。これは、PB が後方と前方の両方を適切に処理するように設計されているもう 1 つのことです (したがって、新しいソフトウェアは古いデータを読み取ることができ、その逆も可能です) - もちろん、提案されたルールに固執する場合:)
Java のパフォーマンスとネイティブのシリアライゼーションに注意を払ってみた結果、いずれにせよ PB の方が高速であることに驚かなかったでしょう。機会があれば、サーバー VM を使用してください。私の最近のベンチマークでは、サーバー VMはサンプル データのシリアライズとデシリアライズで2 倍以上高速であることが示されました。PB コードはサーバー VM の JIT に非常に適していると思います:)
2 つのメッセージ (1 つは 228 バイト、もう 1 つは 84750 バイト) をシリアライズおよびデシリアライズするサンプル パフォーマンス数値と同様に、サーバー VM を使用してラップトップで次の結果を得ました。
ファイル google_message1.dat を使用した Benchmarks.GoogleSize$SizeMessage1 のベンチマーク
バイト文字列にシリアル化: 30.16 秒で 2581851 回の繰り返し。18.613789MB/秒
バイト配列にシリアル化: 29.842 秒で 2583547 回の繰り返し。18.824497MB/秒
メモリ ストリームへのシリアル化: 30.125 秒で 2210320 回の反復。15.953759MB/秒
バイト文字列からデシリアライズ: 30.088 秒で 3356517 回の繰り返し。24.256632MB/秒
バイト配列からの逆シリアル化: 29.958 秒で 3356517 回の反復。24.361889MB/秒
メモリ ストリームから逆シリアル化: 29.821 秒で 2618821 回の反復。19.094952MB/秒
ファイル google_message1.dat を使用した Benchmarks.GoogleSpeed$SpeedMessage1 のベンチマーク
バイト文字列にシリアル化: 29.978 秒で 17068518 回の繰り返し。123.802124MB/秒
バイト配列にシリアル化: 30.043 秒で 17520066 回の繰り返し。126.802376MB/秒
メモリ ストリームへのシリアル化: 30.076 秒で 7736665 回の反復。55.93307MB/秒
バイト文字列からデシリアライズ: 30.073 秒で 16123669 回の繰り返し。116.57947MB/秒
バイト配列からの逆シリアル化: 30.109 秒で 16082453 回の繰り返し。116.14243MB/秒
メモリ ストリームからのデシリアライズ: 30.03 秒で 7496968 回の反復。54.283176MB/秒
ファイル google_message2.dat を使用した Benchmarks.GoogleSize$SizeMessage2 のベンチマーク
バイト文字列へのシリアル化: 30.034 秒で 6266 回の繰り返し。16.826494MB/秒
バイト配列へのシリアル化: 30.027 秒で 6246 回の繰り返し。16.776697MB/秒
メモリ ストリームへのシリアル化: 29.916 秒で 6042 回の反復。16.288969MB/秒
バイト文字列からの逆シリアル化: 29.819 秒で 4675 回の繰り返し。12.644595MB/秒
バイト配列からの逆シリアル化: 30.093 秒で 4694 回の繰り返し。12.580387MB/秒
メモリ ストリームからの逆シリアル化: 29.579 秒で 4544 回の反復。12.389998MB/秒
ファイル google_message2.dat を使用した Benchmarks.GoogleSpeed$SpeedMessage2 のベンチマーク
バイト文字列にシリアル化: 30.055 秒で 39562 回の繰り返し。106.16416MB/秒
バイト配列にシリアル化: 30.178 秒で 39715 回の繰り返し。106.14035MB/秒
メモリ ストリームへのシリアル化: 30.032 秒で 34161 回の反復。91.74085MB/秒
バイト文字列からの逆シリアル化: 29.794 秒で 36934 回の繰り返し。99.98019MB/秒
バイト配列からの逆シリアル化: 29.915 秒で 37191 回の繰り返し。100.26867MB/秒
メモリ ストリームからの逆シリアル化: 29.846 秒で 36237 回の繰り返し。97.92251MB/秒
「速度」対「サイズ」は、生成されたコードが速度またはコードサイズのどちらで最適化されているかです。(シリアル化されたデータはどちらの場合も同じです。多くのメッセージが定義されていて、コードに多くのメモリを使用したくない場合のために、「サイズ」バージョンが提供されています。)
ご覧のとおり、小さなメッセージの場合、非常に高速になる可能性があります。1 ミリ秒あたり500 を超える小さなメッセージがシリアル化または逆シリアル化されます。87K のメッセージでも、1 メッセージあたり 1 ミリ秒もかかりません。