1

foreach p : allPersonsの例では、マップ/辞書をキャッシング/メモ化に使用できることは明らかです (ロジックがシーケンシャルであるため)。

Dictionary<string, int> personNameToIdMap = new Dictionary<string, int>();

foreach(p : allPersons)
{

 int outputId;

 if(personNameToIdMap.TryGetValue(p.Name, out outputId))
 {
   // nothing to do since map contained the p.Name
 }
 else
 { 
    outputId = doExpensiveLookup(p.Name);
    personNameToIdMap[p.Name] = outputId;
 }

  ...

  p.Id = outputId;

}

上記foreachをに置き換えるとParallel.ForEach、各スレッドは を共有しpersonNameToIdMapますか?

4

2 に答える 2

2

ハリスは完全に正しいです -ConcurrentDictionary<T,U>適切なアプローチでしょう。ConcurrentDictionaryそれを考えると、のメソッドを利用するためにメソッドを少し変更したくなるでしょうGetOrAdd:

ConcurrentDictionary<string, int> personNameToIdMap = new ConcurrentDictionary<string, int>();

Parallel.ForEach(allPersons, p =>
{
    int outputId = personNameToIdMap.GetOrAdd(p.Name, name => doExpensiveLookup(p.Name));

    // ...
    p.Id = outputId;
}
于 2013-08-05T18:19:04.643 に答える