2017-04-11 4 views
2

とループのために私は、forループハンドルは、このような20のバッチでリストに項目を追加することを書かれています。だから私は、並列ループを使うために、10〜15000個の大きなリストを使って作業しているときに、スピードアップを考えていましたか?ループの正規以外のバッチ挿入を行う行うにはどのような方法が速くやり方どこで、そこには...C#の場合と並列バッチロジック

Parallel.For(0,filteredList.Count, i=>{ 
i+=20; 
newlist.Add(GetResponse(filteredList.Skip(i).Take(20))); 
}); 

しかし、これは私の望む結果が得られていません:

私はこのような何かを試してみました実行時間はplain forループよりも改善されるでしょうか?

+1

あなたがこれを行うことはできません...スタートのために、私はnewListはスレッドセーフではありませんね?どのコレクションタイプですか?また、スレッドに送信する前にクエリを具体化する必要がありますので、.Skip()。Take()。ToList()を呼び出して、そのループを渡します。 – Milney

+0

@Milney正しいnewListはスレッドセーフではありません。それを忘れてしまった...リストの代わりに並行バッグを使用したらどうなる? – User987

+1

@ User987なぜ*何か*を使用する。これをPLINQとして書き直し、結果​​をリストに集めることができます。 'filteredList'を生成するフィルタリング演算をPLINQクエリに追加して、演算全体を高速化することができます –

答えて

4

List<T>

Parallel.For(... { 
    ... 
    newlist.Add(GetResponse(filteredList.Skip(i).Take(20))); 
    ... 
    }); 

が間違っ技術である理由です、スレッドセーフではありません。代わりにパラレルLINQの(PLINQ)を使用してみてください:

newList.AddRange(filteredList 
    .AsParallel() 
    .Select((value, index) => new { 
    value = value, 
    index = index }) 
    .GroupBy(item => item.index/20) 
    .Select(chunk => GetResponse(chunk.Select(item => item.value)))); 
+1

結果を 'AddRange'に渡す場合、' ToList() 'は必要ありません。一方、 'newList'に並列演算の結果が含まれている場合は、' ToList() 'の結果を代入するだけです。 –

+1

@Panagiotis Kanavos:ありがとう!あなたは間違いありません:早期のマテリアライゼーション - '.ToList()' - 悪いです –

+0

@DmitryBychenko何らかの理由で、この2行のコードでエラーが発生します:value = value、index = "expected; ? – User987

関連する問題