为Atomic AddOrUpdate扩展C#Dictionary

时间:2016-01-21 00:38:29

标签: c# .net dictionary atomic

之前我在Atomic AddOrUpdate on C# Dictionary上提出了一个问题。基本上我得到的答案是扩展C#Dictionary实现,我发现它非常合理。

我按照建议扩展了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是修改类型的字典):

This my code's CPU profile:

这是字典代码: Dictionary code

比较:最初我的代码没有原子AddOrUpdate大概 2min ,但现在它甚至没有完成!虽然它占用超过 10GB 的RAM并且永远需要!!

我错过了一点吗?

1 个答案:

答案 0 :(得分:0)

我想这与您删除IEqualityComparer的设置有关。

但是,我建议您只使用Insert方法中的添加标记设置为false来调用原始AddOrUpdate,而不是调整插入方法。因为Insert基本上就像添加或更新方法一样。