質問

今後のプロジェクトで実行しようと考えているキャッシュについては、Java シリアル化について考えています。つまり、使用すべきでしょうか?

さて、私は過去数年にさまざまな理由でカスタムのシリアル化と逆シリアル化 (外部化可能) を作成しました。最近では、相互運用性がさらに重要な問題となっており、.Net アプリケーションと対話する必要性が予測できるため、プラットフォームに依存しないソリューションの使用を考えました。

GPB を高性能で使用した経験のある人はいますか?速度と効率の点で Java のネイティブ シリアル化と比較するとどうですか?あるいは、検討する価値のある他のスキームはありますか?

役に立ちましたか?

解決

速度に関してはプロトコルバッファとJavaのネイティブシリアル化を比較していませんが、相互運用性のためにJavaのネイティブシリアル化は重大な問題です。また、ほとんどの場合、プロトコルバッファほどスペースに関して効率的ではありません。もちろん、保存できるものや参照などの点で多少柔軟性があります。プロトコルバッファは、目的に非常に優れており、必要に応じて最適です-しかし、相互運用性のために明らかな制限があります(その他)。

最近、Javaと.NETのプロトコルバッファベンチマークフレームワークを投稿しました。 Javaバージョンは、メインのGoogleプロジェクトベンチマークディレクトリ)、. NETバージョンは私のC#ポートプロジェクト。 PBの速度とJavaのシリアル化の速度を比較する場合は、同様のクラスを作成してベンチマークを実行できます。ただし、相互運用に興味がある場合は、ネイティブJavaシリアル化(または.NETネイティブバイナリシリアル化)について再考するつもりはありません。

プロトコルバッファー以外にも相互運用可能なシリアル化のためのオプションがあります- Thrift JSON および YAML 心に湧き、そして間違いなく他のものがあります。

編集:わかりました。相互運用はそれほど重要ではないので、シリアル化フレームワークから必要なさまざまな品質をリストしてみる価値があります。あなたが考えるべき1つのことはバージョン管理です-これはPBが逆方向と順方向の両方をうまく処理するように設計された別のことです(したがって、新しいソフトウェアは古いデータを読み取ることができ、逆も同様です)-もちろん、提案されたルールに固執するとき:)

Javaのパフォーマンスとネイティブシリアライゼーションの両方に注意を払おうとしても、PBの方が高速であることに驚くことはありません。機会があれば、サーバーvmを使用してください。最近のベンチマークでは、サンプルデータのシリアル化と非シリアル化でサーバーVMが 2倍以上高速であることが示されました。 PBコードはサーバーVMのJITに非常によく合っていると思います:)

2つのメッセージ(1つの228バイト、1つの84750バイト)のシリアル化と非シリアル化のサンプルパフォーマンス値として、サーバーVMを使用してラップトップで次の結果を得ました:

Benchmarking benchmarks.GoogleSize$SizeMessage1 with file google_message1.dat 
Serialize to byte string: 2581851 iterations in 30.16s; 18.613789MB/s 
Serialize to byte array: 2583547 iterations in 29.842s; 18.824497MB/s 
Serialize to memory stream: 2210320 iterations in 30.125s; 15.953759MB/s 
Deserialize from byte string: 3356517 iterations in 30.088s; 24.256632MB/s 
Deserialize from byte array: 3356517 iterations in 29.958s; 24.361889MB/s 
Deserialize from memory stream: 2618821 iterations in 29.821s; 19.094952MB/s 

Benchmarking benchmarks.GoogleSpeed$SpeedMessage1 with file google_message1.dat 
Serialize to byte string: 17068518 iterations in 29.978s; 123.802124MB/s 
Serialize to byte array: 17520066 iterations in 30.043s; 126.802376MB/s 
Serialize to memory stream: 7736665 iterations in 30.076s; 55.93307MB/s 
Deserialize from byte string: 16123669 iterations in 30.073s; 116.57947MB/s 
Deserialize from byte array: 16082453 iterations in 30.109s; 116.14243MB/s
Deserialize from memory stream: 7496968 iterations in 30.03s; 54.283176MB/s 

Benchmarking benchmarks.GoogleSize$SizeMessage2 with file google_message2.dat 
Serialize to byte string: 6266 iterations in 30.034s; 16.826494MB/s 
Serialize to byte array: 6246 iterations in 30.027s; 16.776697MB/s 
Serialize to memory stream: 6042 iterations in 29.916s; 16.288969MB/s 
Deserialize from byte string: 4675 iterations in 29.819s; 12.644595MB/s 
Deserialize from byte array: 4694 iterations in 30.093s; 12.580387MB/s 
Deserialize from memory stream: 4544 iterations in 29.579s; 12.389998MB/s 

Benchmarking benchmarks.GoogleSpeed$SpeedMessage2 with file google_message2.dat 
Serialize to byte string: 39562 iterations in 30.055s; 106.16416MB/s 
Serialize to byte array: 39715 iterations in 30.178s; 106.14035MB/s 
Serialize to memory stream: 34161 iterations in 30.032s; 91.74085MB/s 
Deserialize from byte string: 36934 iterations in 29.794s; 99.98019MB/s 
Deserialize from byte array: 37191 iterations in 29.915s; 100.26867MB/s 
Deserialize from memory stream: 36237 iterations in 29.846s; 97.92251MB/s 

"速度" vs"サイズ"生成されたコードが速度とコードサイズのどちらに最適化されているかです。 (シリアル化されたデータはどちらの場合も同じです。「サイズ」バージョンは、多くのメッセージが定義されており、コード用に大量のメモリを使用したくない場合に提供されます。)

ご覧のとおり、小さいメッセージの場合、非常に高速になります-500を超える小さなメッセージが1ミリ秒ごとにシリアライズまたはデシリアライズされます。 87Kのメッセージでも、メッセージあたり1ミリ秒未満しかかかりません。

他のヒント

もう1つのデータポイント:このプロジェクト:

http://code.google.com/p/thrift-protobuf-compare /

PBでのJavaシリアル化を含む、小さなオブジェクトの期待されるパフォーマンスのアイデアを提供します。

結果はプラットフォームによって大きく異なりますが、いくつかの一般的な傾向があります。

FST もご覧ください。 JDKのシリアル化では、高速で出力が小さくなるはずです。

最近行った頻繁なベンチマークの生の推定:

100%=バイナリ/構造ベースのアプローチ(SBE、fst-structなど)

  • 不便な
  • 後処理(受信側で" real"オブジェクトを構築)はパフォーマンス上の利点を損なう可能性があり、ベンチマークには含まれません

〜10%-35%protobuf&派生物

〜10%-30%FSTやKRYOなどの高速シリアライザー

  • 便利なデシリアライズされたオブジェクトは、ほとんどの場合、追加の手動翻訳コードなしで直接使用できます。
  • パフォーマンスを向上させることができます(注釈、クラスの登録)
  • オブジェクトグラフのリンクを保持します(2回シリアル化されたオブジェクトはありません)
  • 周期構造を処理できます
  • 汎用ソリューション、FSTはJDKシリアル化と完全に互換性があります

〜2%-15%JDKシリアル化

〜1%-15%高速JSon(例:ジャクソン)

  • オブジェクトグラフは処理できませんが、Javaデータ構造の小さなサブセットのみを処理できます
  • 参照の復元なし

0.001-1%フルグラフJSon / XML(例:JSON.io)

これらの数値は、非常に大雑把な印象を与えるためのものです。 パフォーマンスは、シリアル化/ベンチマークされるデータ構造に大きく依存することに注意してください。そのため、単一の単純なクラスベンチマークはほとんど役に立ちません(しかし、人気があります:たとえば、Unicodeを無視し、コレクションがないなど)。

また参照

http://java-is-the-new-c.blogspot.de/2014/12/a-persistent-keyvalue-server-in-40.html

http: //java-is-the-new-c.blogspot.de/2013/10/still-using-externalizable-to-get.html

速度と効率の点で PB とネイティブ Java シリアル化のどちらを使用するか迷っている場合は、PB を選択してください。

  • PBはそうした要素を実現するために設計されました。見る http://code.google.com/apis/protocolbuffers/docs/overview.html
  • PB データは非常に小さいのに対し、Java シリアル化は署名を含むオブジェクト全体を複製する傾向があります。なぜいつもクラス名やフィールド名を取得してしまうのか...受信側では知り尽くしているのに、連載中?
  • 言語発達全体について考えてみましょう。一方が Java を使用し、一方が C++ を使用すると、難しくなります...

Thrift を勧める開発者もいますが、私は「Google を信じている」ので Google PB を使います :-)..とにかく、一見の価値があります:http://stuartsierra.com/2008/07/10/thrift-vs-protocol-buffers

高性能とはどういう意味ですか?ミリ秒のシリアル化が必要な場合は、最も単純なシリアル化アプローチを使用することをお勧めします。サブミリ秒が必要な場合は、バイナリ形式が必要になる可能性があります。 10マイクロ秒よりずっと短い時間が必要な場合は、カスタムシリアル化が必要になる可能性があります。

シリアル化/逆シリアル化のベンチマークはあまり見ていませんが、シリアル化/逆シリアル化で200マイクロ秒未満をサポートするものはほとんどありません。

プラットフォームに依存しないフォーマットには、コストと労力がかかるため、パフォーマンスとプラットフォームのどちらを独立させるかを決定する必要があります。ただし、必要に応じて切り替える設定オプションとして両方を使用できない理由はありません。

今日の壁の提案は次のとおりです:-)(あなたが今試したいことを頭の中で微調整しました)...

これを介してキャッシュソリューション全体を使用できる場合、 Project Darkstar が機能する可能性があります。これは非常に高性能なゲームサーバーとして設計されており、特に読み取りが高速になります(キャッシュに適しています)。 JavaとC APIがあるので、Javaを使用してオブジェクトを保存し、Cでオブジェクトを保存したり、Cでそのオブジェクトを読み戻したりできると思います(私はそれを見てから長い時間が経っていたと思っていました)。

他に何もない場合は、今日読むべきものを提供します:-)

ワイヤフレンドリーなシリアル化を行うには、Externalizableインターフェイスの使用を検討してください。巧妙に使用すると、特定のフィールドを最適にマーシャリングおよびアンマーシャリングする方法を決定するための詳細な知識が得られます。ただし、各オブジェクトのバージョン管理を正しく管理する必要があります-マーシャリング解除は簡単ですが、コードがV1をサポートしているときにV2オブジェクトを再マーシャリングすると、アプリが壊れたり、情報が失われたり、データが破損したりします正しく処理できません。最適なパスを探している場合、妥協することなく問題を解決できるライブラリはないことに注意してください。一般に、ライブラリはほとんどのユースケースに適合し、アクティブなオープンソースプロジェクトを選択した場合、入力なしで時間の経過とともに適応および強化されるという追加の利点があります。そして、パフォーマンスの問題を追加したり、バグを導入したり、まだ影響を与えていないバグを修正したりすることもあります!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top