2012-01-12 12 views
2

私は、直列化オブジェクトのグラフを含むファイルにバイナリデータフォーマットを書いています。エラーに対してより弾力性があり、問題をデバッグできるようにするために、ストリーム内の各オブジェクトに長さ接頭辞を付けることを検討しています。私は現在、C#とBinaryWriterを使用していますが、それはかなり一般的な問題です。長さのプレフィックス付きバイナリデータを効率的に書く方法

それは多くの戦略がある長さのプレフィックスを書き込むよう することができるように、完全にシリアライズされるまで、各オブジェクトの大きさが不明である。

  1. 十分で書き込みバッファを使用するとスペースを使用してランダムアクセスを行い、オブジェクトがシリアル化された後で長さを正しい位置に挿入します。

  2. 各オブジェクトを独自のMemoryStreamに書き込んだ後、バッファの長さとバッファの内容をメインストリームに書き込みます。

  3. 最初のパスですべてのオブジェクトの長さをゼロに書き、ファイル内のすべてのオブジェクトサイズ(サイズを設定するオブジェクトのテーブル)の位置を覚えて、すべてのサイズで2番目のパスを埋めます。

  4. ??

合計サイズ(及び第一/最外オブジェクトのこのようサイズ)は1メガバイトの周りに典型的であるが、50〜100メガバイトと大きくすることができます。私の懸念事項は、プロセスのパフォーマンスとメモリ使用量です。

どの戦略が最も効率的でしょうか?

+0

シリアル化する前にサイズを計算するのを止めるのはなぜですか?あなたのバイナリシリアル化のどの部分が非決定的ですか? – Jodrell

+0

これは非決定的ではありませんが、シリアライゼーションコード自体はサイズの仕様とほぼ同じです。例えば、シリアライゼーションは、ファイルフォーマットのバージョン(以前のフォーマットとして保存する場合)などに応じて、シリアライズ/デシリアライズメソッドによって異なるパスをとることがあります。それが決定論的であっても、本当に難しいでしょう。 –

答えて

0

どの戦略が最も効率的でしょうか?

これを判断する唯一の方法は、測定することです。

私の最初の本能は#2を使用することですが、それがGCに圧力をかける可能性が高いことを知っています(ワーカーストリームが80Kbを超えると、大きなオブジェクトヒープに断片化する)。しかし、#3は興味深いと思います。それらのポジションを追跡する複雑さは保守性には影響しません。

最後に、データで測定する必要があり、異常な状況が発生しない限り、パフォーマンスはメモリで処理されるのではなく、ネットワークまたはストレージのパフォーマンスによって支配されることに注意してください。

0

100MBは、「小」サイズのサーバー(または標準のデスクトップコンピュータ)のメモリのわずか2.5%です。私はメモリ(たとえば、BinaryWriterでbyte [] array/MemoryStream)にシリアル化し、完了したらディスクにフラッシュします。

これはまた、きれいなコンパクト、および管理が容易なコードを続けるだろう - あなたの髪を引き裂くの時間からあなたを節約し、大きなブロブに前後に求めている:)

・ホープ、このことができます!

0

フォーマットを制御すると、オブジェクトサイズのリストが累積され、ファイルの最後にディレクトリが追加されます。しかし、.NETの世界では、書き込みバッファが何回かコピーされてから実際にディスクに転送されることを忘れないでください。したがって、余分なものを避けて(例えば)MemoryStreamとすることで得られる利益は、全体の効率を大幅に上げることはありません。

関連する問題