4

オブジェクトを非常に迅速にメモリに読み込む必要があるソリューションがありますが、ディスク io の時間を節約するために、バイナリ ストリームが圧縮されてメモリにキャッシュされる場合があります。

私はさまざまなソリューションをいじくり回しましたが、明らかに XmlTextWriter と XmlTextReader はあまり良くなく、組み込みのバイナリシリアル化もそうではありませんでした。Protobuf-net は優れていますが、それでも少し遅すぎます。ここにいくつかの統計があります:

ファイル サイズ XML: 217 kb

ファイルサイズ バイナリ: 87 kb

圧縮バイナリ: 26 KB

圧縮された XML: 26 KB

XML でデシリアライズ (XmlTextReader) : 8.4 秒

バイナリでデシリアライズ (Protobuf-net): 6.2 秒

Binary wo string.interning (Protobuf-net) でデシリアライズ: 5.2 秒

Binary でデシリアライズメモリから: 5.9 Sek

バイナリ ファイルをメモリに解凍する時間: 1.8 秒

Xml でシリアライズ (XmlTextWriter) : 11 秒

バイナリ (Protobuf) でシリアル化: 4 秒

バイナリ長のプレフィックス (Protobuf-net) でシリアル化: 3.8 秒

逆シリアル化の主な原因は、IO ではなく実際のバイト変換であるように思われます (間違っている場合は訂正してください)。その場合は、新しい Parallel 拡張機能を使用する候補になるはずです。

私はバイナリIOに関しては少し初心者なので、解決に時間を割く前にいくつかの意見をいただければ幸いです:)

簡単にするために、オプションのフィールドを持たないオブジェクトのリストを逆シリアル化するとします。私の最初のアイデアは、それぞれに長さの接頭辞を付けて保存することでした。それぞれの byte[] を byte[] のリストに読み取り、PLINQ を使用して byte[] -> オブジェクトの逆シリアル化を実行します。

ただし、その方法では、バイト [] をシングルスレッドで読み取る必要があるため、代わりにバイナリ ストリーム全体をメモリに読み込むことができます (ところで、バイナリ ファイルの大きさはどれくらいですか?)。多くのオブジェクトがあり、それぞれの長さとオフセットがあります。次に、ArraySegments などを作成して、チャンクも並列に実行できるようにする必要があります。

それで、あなたはどう思いますか、それは実現可能ですか?

4

4 に答える 4

2

私はこのようなことをかなり頻繁に行いますが、BinaryReader を使用して内容を読み取ることに勝るものはありません。私が知る限り、BinaryReader.ReadInt32 を使用して 32 ビット整数を読み取るよりも高速な方法はありません。

また、並列化して再び結合するオーバーヘッドが大きすぎることに気付くかもしれません。本当に並列ルートに進みたい場合は、複数のブロックで 1 つのファイルを読み取る複数のスレッドではなく、複数のスレッドを使用して複数のファイルを読み取ることをお勧めします。

ブロック サイズをいじってディスクのブロック サイズと一致させることもできますが、アプリケーションとディスクの間に非常に多くのレベルの抽象化があるため、時間の無駄になる可能性があります。

于 2009-12-23T10:48:09.757 に答える
1

逆シリアル化の主な原因は、IO ではなく実際のバイト変換であるように思われます (間違っている場合は訂正してください)。

どこで時間が費やされているかを推測せず、プロファイラーを入手して調べてください。

于 2009-12-23T09:52:57.527 に答える
1

バイナリ ファイルは、複数のスレッドで同時に読み取ることができます。これを行うには、適切なアクセス/共有修飾子で開く必要があります。そして、各スレッドはそのファイルで独自のオフセットと長さを取得できます。したがって、並行して読み取ることは問題ではありません。

単純なバイナリ形式に固執すると仮定しましょう。各オブジェクトには、その長さがプレフィックスとして付けられます。ファイルを「スクロール」して、逆シリアル化スレッドを配置するオフセットを知ることができます。

デシリアライズ アルゴリズムは次のようになります。1) ファイルを分析します (ファイルをいくつかの比較的大きなチャンクに分割します。チャンクの境界はオブジェクトの境界と一致する必要があります) 2) 必要な量のデシリアライザー スレッドを生成し、適切なオフセットと長さで読み取りを「指示」します 3)すべてのデシリアライザー スレッドの結果を 1 つのリストに結合する

于 2009-12-22T13:29:33.767 に答える