1

すべて倍精度のデータのセットがあります: 100 行 20 列

次のようにして、データを IEnumerable リストに取り込みます。

var RowsOfData = File.ReadLines(dll.Globals.OutputDir +     dll.Globals.filename).Select(a => a.Split(',').ToList());

var FilteredRowsToday = (from n in RowsOfData
       where n[1] == 1
       orderby n[0] descending
       select n);

次に、データ行ごとに簡単なチェックを行い、それぞれが Bool を返す一連の関数を用意します。私が欲しいのは、各関数が真と評価された行の数です。そして、プロジェクトをスケールアップするとき、可能であればこれをできるだけ早く並行して処理したいので、試しました:

foreach (var row in FilteredRowsToday) {  
is f1() true, is f2() true 
etc
}

並行してやろうとしたのが遅いようです

foreach (var row in FilteredRowsToday.AsParallel())

速くない

私は今、次のようなことを考えています:

var TotalTrue = FilteredRowsToday.Select(item => f1() & f2() & f3()).Count();

データを前処理して、各関数の評価結果を一種のバイナリ グリッドとして提供できますか?

F1, f2, f3 etc
1, 0, 0 row 1
1, 1, 1 row 2 etc

提案を歓迎します!

4

2 に答える 2

1

3 つの関数すべてが true と評価されるカウントだけに関心がある場合は、これで十分です。

var TotalTrue = FilteredRowsToday.Count(item => f1() & f2() & f3());

遅い理由については、関数が原因である可能性があります。

3 つの関数すべてが true を返すか、少なくとも 1 つの関数が false を返すまで、行のみを評価してみることができます。

var TotalTrue = FilteredRowsToday.Count(item => f1() && f2() && f3());

つまり、 Iff1()が と評価された場合falseは、残りの検証を行う必要はありません。

更新:関数がリソースを集中的に使用するチェックを行っていない場合、並列 LINQ はあまり役に立ちません (詳細はこちら)。

于 2012-11-06T20:43:46.640 に答える
0

ご覧のとおり、一度にファイルを読み取っていますが、これは一種のカンマ区切りファイルです。読み取り時にファイルからレコードを取得すると、次の読み取りを待つまでそれらを処理できます。

private IEnumerable<string> GetRecords(string fileName) {
    using (StreamReader reader = File.OpenText(fileName))
            {
                string line = reader.ReadLine();
                while (line != null)
                {   
                   yield return line.Split(',');
                   line = reader.ReadLine();
                 }
             }
}

また、クエリの実行に必要なインデックスへのアクセスが既にあり 、その結果を にSplit変換するのにも時間を費やしています。Listarray

.Count(item => f1() & f2() & f3());の代わりに使用するなど、前に提案された最適化を適用することもお勧めします.Select(item => f1() & f2() & f3()).Count();

それにもかかわらず、この最適化のいずれかが、このような少量のデータで改善をもたらすとは思いません。コードの処理部分に関する詳細を投稿していただければ、より良いサポートができると思います。

于 2012-11-06T22:33:15.057 に答える