以前我问过一个关于Atomic AddOrUpdate on C# Dictionary的问题。基本上我得到的答案是扩展C#Dictionary
实现,我发现它很合理。扩展C#字典for Atomic AddOrUpdate
我按照建议扩展了Dictionary
实现,但是,性能出人意料的糟糕!然后我试着尽量减少对C#实现的调整来追踪原因。我能够达到的最小值是:我创建了一个AddOrUpdate
函数,它与Add
的签名非常相似,除了它返回bool
(如果字典包含key
并且其值更新为给定的value
),否则为false。基本上on this source code我做了以下修改:
public bool AddOrUpdate(TKey key, TValue value)
{
return Insert(key, value);
}
和
private bool Insert(TKey key, TValue value)
{
if (buckets == null) Initialize(0);
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int targetBucket = hashCode % buckets.Length;
for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
{
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
{
entries[i].value = value;
version++;
return true; // on original code, it returns void
}
}
int index;
if (freeCount > 0)
{
index = freeList;
freeList = entries[index].next;
freeCount--;
}
else {
if (count == entries.Length)
{
Resize();
targetBucket = hashCode % buckets.Length;
}
index = count;
count++;
}
entries[index].hashCode = hashCode;
entries[index].next = buckets[targetBucket];
entries[index].key = key;
entries[index].value = value;
buckets[targetBucket] = index;
version++;
return false; // on original code, does not return anything
}
我异型在我的代码的CPU性能,下面是一些快照(注:lambdas
是改良型的字典):
比较:最初我没有原子AddOrUpdate代码正在采取大致2分钟,但现在它甚至不完成!而它占用RAM的超过10GB并且永远占用!
我错过了一个观点吗?
'IEqualityComparer'?!不,我没有改变它。基本上比较器总是由'TKey'在这个场景和之前提供。 – Hamed
此外,我没有看到'bool'标志的'Insert'如何作为'AddOrUpdate'工作,至少通过返回一个'boolean'表示添加或更新了该键。 – Hamed
如果你看看代码,你会得到它。插入方法首先检查循环中是否存在像传入方法的键。如果将add设置为true,则会在存在相同的密钥时引发异常。如果它设置为false,它将简单地设置新值并返回。 当for循环完成时,它知道没有提供的键在字典中出现,因此添加它。 –