7

概要: System.Threading.Tasks.Parallel.ForEach と Concurrent Data 構造から単純な plinq (Parallel Linq) クエリに変更しました。スピードアップはすごかった。

plinq は本質的に Parallel.ForEach よりも速いのでしょうか? または、タスクに固有のものです。

// Original Code
// concurrent dictionary to store results
var resultDict = new ConcurrentDictionary<string, MyResultType>();

Parallel.ForEach(items, item =>
        {
            resultDict.TryAdd(item.Name, PerformWork(source));
        });


// new code

var results =
            items
            .AsParallel()
            .Select(item => new { item.Name, queryResult = PerformWork(item) })
            .ToDictionary(kv => kv.SourceName, kv => kv.queryResult);

: 各タスク (PerformWork) は 0 ~ 200 ミリ秒で実行されるようになりました。以前は最適化するまでに時間がかかりました。そのため、最初に Tasks.Parallel ライブラリを使用していました。そのため、合計時間は 2 秒から 100 ~ 200 ミリ秒になり、ほぼ同じ作業を別の方法で実行しました。(すごい linq と plinq は素晴らしいです!)

質問:

  1. plinq と Parallel.ForEach を使用することで速度が向上しますか?
  2. 代わりに、単に並行データ構造 (ConcurrentDictionary) を削除するだけですか? (スレッドを同期する必要がないため)。
  3. この関連する質問の回答に基づいて

PLINQ は主に、副作用のない関数型プログラミング スタイルに基づいていますが、副作用はまさに TPL の目的です。物事を並行して検索/選択するのではなく、実際に並行して作業を行いたい場合は、TPL を使用します。

私のパターンは基本的に機能しているため (入力を与えると、突然変異なしで新しい出力が生成される)、plinq が使用する正しいテクノロジであると仮定できますか?

私の仮定が正しいという検証、または何かが欠けているという兆候を探しています。

4

2 に答える 2

4

Parallel.ForEachこれら 2 つのコード サンプルを使用して、と PLINQ を明確に比較することはできません。コード サンプルは単純に違いすぎます。

最初に飛び出す項目は、最初のサンプルの使用ConcurrentDictionaryと 2 番目の使用Dictionaryです。これら 2 つのタイプの用途とパフォーマンス特性は大きく異なります。2 つのテクノロジーを正確に比較するには、ここでタイプを一致させる必要があります。

于 2011-03-04T16:12:23.813 に答える
2

サンプルで提供した限られた情報に基づいて(OPのコメントで詳細を尋ねました)、使用されているパーティショニングアルゴリズムによる違いが見られると思います。このブログ投稿でチャンクパーティショニングとレンジパーティショニングについて読んでください。彼は、それらの違いと、どのタイプの作業に最も適しているかについて説明しています。このブログ記事と、これら2つのタイプについてもう少し詳しく説明しているブログ記事と、サンプルには適用できませんが、使用できる他の2つのタイプのパーティション分割について詳しく説明しているブログ記事を読むことを強くお勧めします。パーティショニングをよりよく理解します。最後に、ここにさらに別のブログ投稿がありますこれは、作業の分割と、デフォルトの分割アルゴリズムが特定のワークロードに意味をなさない場合にどのように影響するかについて説明しています。その投稿は、実際には、PFXチームからの一連の並列サンプルの一部である作業中のパーティショナーを視覚化するのに役立つ優れたプログラムを参照しています。

于 2011-03-04T22:21:29.787 に答える