【发布时间】:2016-01-21 00:38:29
【问题描述】:
之前我在Atomic AddOrUpdate on C# Dictionary 上问过一个问题。基本上我得到的答案是扩展 C# Dictionary 实现,我觉得这很合理。
我按照建议扩展了Dictionary 实现,但是,性能出奇的差!!然后我尝试尽量减少对 C# 实现的调整以追踪原因。我可以达到的最小值是:我创建了一个AddOrUpdate 函数,它与Add 具有非常相似的签名,除了它返回bool 如果字典包含key 并且它的值由给定的value 更新,否则为假。基本上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 分钟,但现在它甚至没有完成!而它占用超过 10GB 的 RAM 并且永远占用!!
我错过了一点吗?
【问题讨论】:
标签: c# .net dictionary atomic