是否可以在C#中获取对字典项的引用?

时间:2012-06-10 21:01:37

标签: c# dictionary

我正在一个被调用数亿次的函数上实现一个缓存。缓存大小是数千万个项目。 它目前使用Dictionary实现,其中的查找需要花费大量时间。

是否有可能在Dictionary中获取对整个对的引用,而不仅仅是值,因此我可以检查是否存在值,检查它(并且可能更新它)一次查找?

目前,我有这样的事情:

int val;
if (cache.TryGetValue(key, out val))
    if (val < newVal) cache[key] = newVal;
    else return val;
else
    cache.Add(key, newVal);

我想得到这个:

Pair pair = cache.GetPair(key);
if (pair != null)
    if (pair.Value < newVal) pair.Value = newVal;
    else return pair.Value;
else
    cache.Add(key, newVal);

如果有替代数据结构允许这样做,我也很高兴听到它。

提前致谢!

3 个答案:

答案 0 :(得分:4)

这是受Mare Infinitus回答的启发。假设您的cache变量现在为Dictionary<string, int>,您可以将其更改为Dictionary<string, MutableInt32>,其中MutableInt32的编写如下:

// wraps an int that may change
class MutableInt32
{
  public int Value;
}

然后您可以将代码更改为

MutableInt32 val;
if (cache.TryGetValue(key, out val))
  if (val.Value < newVal) val.Value = newVal;
  else ...

答案 1 :(得分:2)

你的想法很好,因为它减少一半的字典内的hash-and-find-bucket操作。我自己对这些东西进行了基准测试,并且字典没有人们想象的那么快。

不幸的是,内置字典不支持此功能。甚至没有解决方法。

您可以实现自己的哈希表并自行完成。除了法律问题,您可以从Dictionary的实现开始并添加GetAndUpdateOrCreate方法。

答案 2 :(得分:2)

您当然可以将Pairs存储在字典中!

public class KeyValueTuple
{
    private string key;
    private int value;

    public KeyValueTuple(string key, int value)
    { 
        this.key = key;
        this.value = value;
    }
}

public class BigDataCache
{
    private Dictionary<string, KeyValueTuple> cache;

    public BigDataCache()
    {
        cache = new Dictionary<string, KeyValueTuple>();

        cache.Add("entry1", new KeyValueTuple("entry1", 1));
        cache.Add("entry2", new KeyValueTuple("entry2", 2));
        cache.Add("entry3", new KeyValueTuple("entry3", 3));
    }

    public KeyValueTuple GetTuple(string key)
    {
        KeyValueTuple value = null;

        if (cache.TryGetValue(key, out value))
        {
            return value;
        }

        return null;
    }
}

public void SomeMethod()
{
    BigDataCache d = new BigDataCache();

    var value1 = d.GetTuple("entry1");
    var value2 = d.GetTuple("entryNotValid");
}