以前我問過一個關於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循環完成時,它知道沒有提供的鍵在字典中出現,因此添加它。 –