2012-04-20 11 views
4

他のファイルを組み合わせたり編集したりして大きなファイルを作成するアプリケーションを想像してみてください。例えば 、アプリケーション:.NETアプリケーションの大容量メモリブロック。それらを処理する最適/推奨/スケーラブルな方法は何ですか?

  • は追加画像のアーカイブを開くか、
  • は画像
  • の結果セットで新しいアーカイブを作成し、既存の画像の一部を変更した画像の一部を置き換えます

イメージの追加/置換/変更は任意の順序で行うことができるため、実行の最後まで新しいアーカイブを作成することはできません。

元のアーカイブ内の各画像に対してMemoryStreamオブジェクトのセットを作成し、必要に応じてストリームを変更/削除/置き換えて、新しいアーカイブに書き込むことは賢明な方法です。そのようなアプローチはおそらく実行速度に関して最良の結果を与えるでしょう。

問題は明らかです。一連のストリームを保持するためのメモリが必ずしも十分ではありません。

この場合、あなたは何をお勧めしますか?

私はメモリのためのいくつかのスピードを交換し、一時的なオフメモリストレージのいくつかの種類を使用する必要がありますね。私は何を使うべきか分からない。

メモリマップファイルを使用する必要がありますか?または、それらの作成と削除のための何らかの仕組みを持つ普通の古い一時ファイル?多分何か?

+1

パフォーマンス要件はありますか?私は単純な一時ファイル(多くの小さなファイルの減速を避けるためにネストされた構造に格納されている可能性があります)のために移動し、そこから開始することに誘惑されます。適切なインターフェースの背後に隠れていると、後でいつでも気をつけることができます! –

+1

MicrosoftのEsentの使用を検討しましたか? Wikiページ:https://en.wikipedia.org/wiki/Extensible_Storage_Engine ESENT Managed .Net lib:https://managedesent.codeplex.com/ –

+0

@JeffFosterもちろん、できるだけ多くの速度を保ちたいと思います。それ以外には特別なパフォーマンス要件はありません。 – Bobrovsky

答えて

2

1つのアプローチは、ファイルとファイルシステムを使用することです(ほとんどの場合)。また、ある種のメモリキャッシュまたはマッピングを提供します。

大量または大量のファイルを処理している場合、余分なハードウェアやRAMを使用している場合を除き、実際にはメモリサイズと一致させることはできません。

具体的には、私は個人的にあなたのファイル、バックエンドでのアーカイブのためのフロントを装っされている... ...何かのように

class MemoryArchive {} 

に行くと思います。

ほとんどのunzipユーティリティと同様に、ディスクの一時ファイルフォルダにアーカイブを展開してから、アクセスの小さいユニット、つまりファイルを処理します。

MemoryArchiveは基本的にすべてがメモリ内にあるように動作しますので、メモリストリーム(またはオブジェクトレベルで直接アクセスするために使用するもの)の代わりに、ディスク上の一時ファイルにマッピングする必要があります。ファイルストリーム。

おそらく、メモリ内の内容がディスク上のコンテンツと同期することを確認するために必要な同期やエラー、または問題を処理する堅牢な方法です。

その時点で(そしてシステムの性質などによって)、主なタスクは、ファイルシステムのストレージ周辺で何らかのトランザクションをコーディングする必要があります。これはデータベース管理システムに似ています。しかし、それは他の「スケールの終わり」にあるでしょう。もしあなたがそれなくして生活し、それを単純に保つことができれば、それは問題ではないかもしれません。

ただ、アイデア、それはすべてあなたの特定の詳細に依存したいのに - メモリがある場合に許可する場合は、ロードができ、すなわち、処理が十分に速い場合 - それは多くを変えることができる(物事の規模すなわち
)、アーカイブ内の「小さな変化」とアーカイブの大きさ、頻度や変更の性質

最も簡単なケースでは、私はかなり一時的なファイルとして物事を保存し、必要に応じて小さなインクリメンタルな変更に対処します。

MemoryArchiveのようなものを使うと、将来のことを垣間見ることができます。それで、あなたはそれを変更することができます。実際にはいくつかの「アプローチの組み合わせ」は、異なるファイルやサイズを扱うときに「すべてに合った解決策」を作ることはほとんどできないので、通常はこれらのシナリオで最も優れています。このことができ、

2

FileStreamを使用して、MemoryStreamと同じ方法で使用できます。基本的には、バッファリングとそのすべてをOS上に決定する負担がかかります。 OSはよく知っていて、ドライバーとハードウェアがキャッシングと微調整の複雑さに気を配ります。理解しやすく、プロフィール、プロフィール、プロフィールのコードを書いてください。

プロファイリングが必要な場合は、2種類のストリームを混ぜて、うまくいくようなものを得ることができます。

+0

これは本質的に平凡な古い一時ファイルです。私もそれらを試してみます。 – Bobrovsky

+1

@Bobrovskyうん、かなり。あなたのプロファイリング結果に基づいたハイブリッドは、おそらくあなたに最高のサービスを提供し、特にチューニングされた結果を提供します。 –

1

メモリマップファイルを使用する必要がありますか?

これは確かに頭に浮かぶ最初のことです。この方法の唯一の問題は、ファイルサイズがすべてのマップされた領域を消費することになります。

+0

多くのファイルを処理する必要があります。多分それらの何千もの。警告ありがとう、マップスペースの制約についてGoogleに尋ねる。 – Bobrovsky

2

まず、あなたはおそらく、」連続して大多数のオブジェクトをしたい作成し、廃棄されているので、もしLOHは、メモリはデフラグしないオブジェクトは基本的に、.net limitation with LOHの点に注意してください

希望"断片化されたメモリホールが十分大きな連続したメモリ空間を与えないかもしれない(.net 4.5以上はある程度これを最適化しましたが、問題は依然として続きます)。あなたの質問に答えるために、たくさんのものがあなたのボックスのアーキテクチャに依存しています。もしそれがたくさんのRAMを備えた64ビットで、あなたのファイルがLOHの問題にちょうど合っていると知っていれば、マイケルは、フィラストリースラッシングが起こるようにバインドされていると示唆した。

+0

LOH制限についての警告をありがとう。私はすでにこの制限の結果を見てきましたが、それについてはわかりませんでした。 – Bobrovsky

関連する問題