私は現在、ロックを使用せずにKey-Valueストレージから値を取得する方法を必要とする非常にパフォーマンスが重要なコードを書いています。
ConcurrentDictionaryを使用してみましたが、この場合のニーズには十分ではありません。
したがって、ここで私が求めているのは、ConcurrentDictionaryにあるGetOrAddメソッドに似ていますが、超高速(ロックなし)であり、スレッドセーフである必要があります:)
ここで、ほとんどの場合、既存の値の取得を行い、新しい値を追加することはめったにないと想定されていることに注意してください。また、このリストはそれほど大きくなることはないと想定されています。
私はスレッディングの専門家ではないので、誰かが私が思いついたものについてコメントできればいいのですが。
public class Registry<TKey, TValue>
{
private Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
{
TValue value;
if (!dictionary.TryGetValue(key, out value))
{
var snapshot = new Dictionary<TKey, TValue>(dictionary);
if (!snapshot.TryGetValue(key, out value))
{
value = valueFactory(key);
snapshot.Add(key, value);
dictionary = snapshot;
}
}
return value;
}
}
ここでの「トリック」は、実際に新しい値を追加する必要がある場合に、実際の辞書のスナップショットを作成することです。最後に、辞書変数がスナップショットを指すように参照を交換します。あちこちでアップデートを1つか2つ失っても、私は本当に気にしないことを忘れないでください。私が必要としているのは、既存の値を本当に高速に取得することです。
参照を交換するコードについては少しわかりません。
辞書=スナップショット;
参照が交換されると同時に別のスレッドがディクショナリ変数にアクセスしようとするとどうなりますか。それもここでの問題ですか?
よろしく
ベルンハルトリヒター