我试图在MemoryCache对象中缓存昂贵函数的结果。
MemoryCache需要一个字符串的键,所以我想知道执行以下操作是否有效:
string key = Char.ConvertFromUtf32(myObject.GetHashCode());
if (!_resourceDescriptionCache.Contains(key))
{
_resourceDescriptionCache[key] = ExpensiveFunction(myObject);
}
return (string)_resourceDescriptionCache[key];
使用单个UTF32字符作为潜在大缓存的密钥感觉很奇怪。
答案 0 :(得分:2)
这取决于。
在许多情况下,使用GetHashCode()可能会导致错误的行为:
哈希代码用于在基于哈希表的集合中进行有效插入和查找。哈希码不是永久值。出于这个原因:
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
如果内存缓存(或将来可能发生)发生在与调用它的代码不同的进程或应用程序域中,则表示第3个条件失败。
使用单个UTF32字符作为潜在大缓存的密钥感觉很奇怪。
如果要缓存足够的东西,由于Birthday Problem,32位哈希的冲突率可能会高得令人不快。
当缓存数以千万计的东西时,我使用了一个名为City Hash的64位哈希(由谷歌创建,开源)并取得了很好的成功。您也可以使用Guid,尽管与64位哈希相比,GUID维护密钥的内存是GUID的两倍。
答案 1 :(得分:1)
Hashcodes可能会发生冲突。 return 0;
是GetHashCode
的有效实施。多个密钥将共享一个不是你想要的缓存槽......你会混淆对象。
如果您的代码不能与return 0;
一起使用GetHashCode
,那么您的代码就会被破坏。
选择更好的缓存密钥。
答案 2 :(得分:-1)
内存缓存由普通的C#Dictionary支持。除了提供到期之外,它确实没有什么不同
碰撞的几率是2 ^ 32,这是整数的大小。即使你设法发生碰撞,字典也会有相应的安全措施(通过使用碰撞时的等于)
编辑:只有在字典被赋予未更改的密钥时才会处理密钥冲突(例如:Dictionary())。在这种情况下,由于MemoryCache使用字符串,因此没有碰撞检测。