是否有大型字典的IDictionary实现不会最终在大对象堆上?

时间:2012-10-12 17:43:55

标签: c# .net dictionary

这与.NET Collections and the Large Object Heap (LOH)密切相关。简而言之,如果有超过85K的桶,它会自动在LOH上,当它被释放时是未知的。有没有人意识到基于数组列表或类似的东西的IDictionary的良好实现阻止它进入LOH?

2 个答案:

答案 0 :(得分:4)

您可以使用SortedDictionary,它是二叉树。

如果你需要Dictionary的O(1)性能,或者更接近它的东西,你可以使用一个不同的哈希表实现,它将数据存储在足够小的块中,不会出现在LOH上。我不知道有什么可公开的;我过去使用过SortedDictionary,发现性能下降很小,所以我没有再看了。

答案 1 :(得分:3)

这是一个选项的开始。我假设你可以按照给出的模式来实现其他方法。

只需更改numDictionaries即可确定它是如何分解的。

如果你真的需要,你可以使字典的数量动态,并在现有字典变得足够大时添加更多。

public class NonContigousDictionary<TKey, TValue>
//TODO make this implement IEnumerable, IDictionary, 
//and any other relevant interfaces.
{
    public Dictionary<TKey, TValue>[] dictionaries;

    private readonly int numDictionaries = 5;
    public NonContigousDictionary()
    {
        dictionaries = Enumerable.Range(0, numDictionaries)
            .Select(_ => new Dictionary<TKey, TValue>())
            .ToArray();
    }

    public TValue this[TKey key]
    {
        get
        {
            int hash = key.GetHashCode();
            return dictionaries[GetBucket(hash)][key];
        }
        set
        {
            int hash = key.GetHashCode();
            dictionaries[GetBucket(hash][key] = value;
        }
    }

    public bool Remove(TKey key)
    {
        int hash = key.GetHashCode();
        return dictionaries[GetBucket(hash].Remove(key);
    }

    public void Clear()
    {
        foreach (var dic in dictionaries)
        {
            dic.Clear();
        }
    }

    private int GetBucket(int hash)
    {
        return (hash % numDictionaries + numDictionaries) % numDictionaries;
    }
}
相关问题