1

電話帳のようなエントリがあります:名前+住所。ソースはWebサイトにあり、カウントは1,000レコードを超えています。

質問は:

でどのように使用/実装 ConcurrentDictionaryParallelForeachますか?

私はそれがより良いパフォーマンスをするかどうか尋ねたほうがいいかもしれません:

ConcurrentDictionaryParallelForeach

vs

Dictionaryforeach

名前がキーと重複することは許可されてConcurrentDictionaryいないので、キーが存在しない場合にのみadd()を追加する独自の組み込み関数があることを正しく理解したと思いますTryAddConcurrentDictionaryそのため、すでに処理されている重複キーの追加を許可しないという問題が発生したため、その時点から、バランスが標準シーケンシャルではなく方向に向かっていることがはっきりとわかりました。Dictionary

では、特定のデータソースから名前とアドレスを追加し、Parallelforeachを介してConcurrentDictionaryにロードするにはどうすればよいですか?

4

2 に答える 2

2

カウントは1,000レコードを超えています。

1Kをいくら超えますか?1Kレコードは、並列化の必要なしに、瞬く間に追加されるためです。

さらに、ネットワークを介してデータをフェッチする場合、そのコストは辞書に追加するコストを大幅に削減します。したがって、データのフェッチを並列化できない限り、データを辞書に並列に追加するためにコードをより複雑にする意味はありません。

于 2012-11-28T07:38:37.160 に答える
1

これは静かな古い質問ですが、これは誰かを助けるかもしれません:

ConcurrentDictionaryをチャンクして処理しようとしている場合は、次のようにします。

using System.Collections.Generic;
using System.Threading.Tasks;
using System.Collections.Concurrent;

namespace ConcurrenyTests
{
    public class ConcurrentExample
    {
        ConcurrentExample()
        {
            ConcurrentDictionary<string, string> ConcurrentPairs = new ConcurrentDictionary<string, string>();

            Parallel.ForEach(ConcurrentPairs, (KeyValuePair<string, string> pair) =>
            {
                // Do Stuff with
                string key = pair.Key;
                string value = pair.Value;
            });
        }
    }
}

繰り返し処理したのと同じ長さのオブジェクトが既にない限り、Parallel.ForEachを使用して新しいディクショナリに挿入できるとは思いません。つまり、ダウンロードして辞書に挿入したいテキストドキュメントのURLのリストです。その場合は、次のようなものを使用できます。

using System.Threading.Tasks;
using System.Collections.Concurrent;

namespace ConcurrenyTests
{
    public class ConcurrentExample
    {
        ConcurrentExample()
        {
            ConcurrentDictionary<string, string> ConcurrentPairs = new ConcurrentDictionary<string, string>();
            ConcurrentBag<string> WebAddresses = new ConcurrentBag<string>();

            Parallel.ForEach(WebAddresses, new ParallelOptions { MaxDegreeOfParallelism = 4 }, (string webAddress) =>
            {
                // Fetch from webaddress
                string webText;
                // Try Add
                ConcurrentPairs.TryAdd(webAddress, webText);

                // GetOrUpdate
                ConcurrentPairs.AddOrUpdate(webAddress, webText, (string key, string oldValue) => webText);

            });
        }
    }
}

Webサーバーからアクセスする場合は、帯域幅が詰まらないようにMaxDefreeOfParallelismを増減することをお勧めします。

Parallel.ForEach:https ://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.parallel.foreach?view=netcore-2.2

ParallelOptions:https ://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions?view=netcore-2.2

于 2019-09-27T00:20:06.800 に答える