我正在一个被调用数亿次的函数上实现一个缓存。缓存大小是数千万个项目。
它目前使用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);
如果有替代数据结构允许这样做,我也很高兴听到它。
提前致谢!
答案 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");
}