どちらも目的の不足しているメソッドを持っているため、コペンハーゲン大学http://www.itu.dk/research/c5/から Microsoft のConcurrentDictionaryと C5 を試してみましたが、少なくとも私のユースケースでは非常に遅かったことがわかります (私はDictionary と比較して 5 倍から 10 倍遅いことを意味します。C5 は常にキーと値の両方を並べ替えており、Concurrent Dictionary は呼び出しスレッドについて「心配しすぎている」と思います。私のアルゴリズムはいくつかのエントリを探して置き換えていましたが、最初のキーは削除され、新しいキーが追加されました (ある種のキュー)...あとは、元の .Net mscorelib の辞書を変更することだけでした。Microsoft からソース コードをダウンロードし、辞書を含めました私のソースコードのクラス。コンパイルするには、HashHelpersクラスとThrowHelperクラスだけをドラッグする必要もあります。残ったのは、いくつかの行をコメントアウトすることだけでした (たとえば[DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))]
、いくつかのリソースのフェッチ)。明らかに、不足しているメソッドをコピーしたクラスに追加する必要がありました。また、Microsoft のソース コードをコンパイルしようとしないでください。何時間もそれを行うことになります。私は幸運にもそれを実行することができました。
public bool Remove(TKey key, out TValue value)
{
if (key == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
if (buckets != null)
{
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
{
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
{
if (last < 0)
{
buckets[bucket] = entries[i].next;
}
else
{
entries[last].next = entries[i].next;
}
entries[i].hashCode = -1;
entries[i].next = freeList;
entries[i].key = default(TKey);
value = entries[i].value;
entries[i].value = default(TValue);
freeList = i;
freeCount++;
version++;
return true;
}
}
}
value = default(TValue);
return false;
}
最後に、名前空間を次の行に変更しましたSystem.Collection.Generic.My
。私のアルゴリズムでは、次の行で値を削除するよりも値を取得していた行が 2 行しかありませんでした。それを新しいメソッドに置き換え、7% ~ 10% の安定したパフォーマンス向上を得ました。このユースケースや、ディクショナリを最初から再実装することが適切でない他のケースに役立つことを願っています。