5

大きなテキスト ファイルを処理する必要があるアプリを作成しています (いくつかの異なる種類のレコードでカンマ区切り - データ ストレージ形式を変更する力や傾向がありません)。レコード (多くの場合、ファイル内のすべてのレコードが順番に読み込まれますが、常にではありません) が読み取られ、各レコードのデータが何らかの処理のために渡されます。

現在、アプリケーションのこの部分はシングル スレッドです (レコードの読み取り、処理、次のレコードの読み取りなど)。あるスレッドでキュー内のレコードを読み取り、別のスレッドで処理する方が効率的かもしれないと考えています。小さなブロックで、または利用可能になったときにスレッド化します。

必要なデータ構造やマルチスレッドを適切に実装する方法など、そのようなプログラミングを開始する方法がわかりません。ここでパフォーマンスを向上させる方法について、誰かが何かアドバイスをしたり、他の提案を提供したりできますか?

4

3 に答える 3

3

レコードを処理する時間とレコードを読み取る時間のバランスを取ることができれば、利益が得られる可能性があります。その場合、たとえば同期キューとワーカー (またはいくつか) のデキューと処理など、プロデューサー/コンシューマーのセットアップを使用できます。並列拡張についても調査したくなるかもしれません。読み取りコードのバージョンを作成するのは非常に簡単です。その後(または他のメソッドの 1 つ) は、実際に必要なすべてを実行する必要があります。例えば:IEnumerable<T>Parallel.ForEachParallel

static IEnumerable<Person> ReadPeople(string path) {
    using(var reader = File.OpenText(path)) {
        string line;
        while((line = reader.ReadLine()) != null) {
            string[] parts = line.Split(',');
            yield return new Person(parts[0], int.Parse(parts[1]);
        }
    }
}
于 2010-01-20T21:49:33.163 に答える
1

このチュートリアルを見てください。必要なものがすべて含まれています...これらは、説明したのと同様のケースのコードサンプルを含むマイクロソフトのチュートリアルです。プロデューサーがキューを満たし、コンシューマーがレコードをポップします。

スレッドの作成、開始、および対話

2 つのスレッドの同期: プロデューサーとコンシューマー

于 2010-01-20T21:48:09.313 に答える
1

非同期 I/Oも参照してください。このスタイルでは、メイン スレッドからファイル操作を開始し、バックグラウンドで実行を継続し、完了すると、指定したコールバックを呼び出します。その間、他の作業 (データの処理など) を続行できます。たとえば、非同期操作を開始して次の 1000 バイトを読み取り、既にある 1000 バイトを処理してから、次のキロバイトを待つことができます。

残念ながら、C# で非同期操作をプログラミングするのは少し面倒です。MSDN のサンプルがありますが、まったく良くありません。これは、非同期ワークフローを使用して F# で適切に解決できます。問題を説明し、 C# iteratorsを使用して同様のことを行う方法を示す記事を書きました。

C# のより有望なソリューションは、C# イテレータを使用した同様のトリックをサポートする Wintellect PowerThreading ライブラリです。Jeffrey Richter によるMSDN Concurrency Affairsの優れた紹介記事があります。

于 2010-01-20T22:18:16.667 に答える