2

我正在尝试在 MemoryCache 对象中缓存昂贵函数的结果。

MemoryCache 需要一个字符串键,所以我想知道执行以下操作是否有效:

string key = Char.ConvertFromUtf32(myObject.GetHashCode());
if (!_resourceDescriptionCache.Contains(key))
{
    _resourceDescriptionCache[key] = ExpensiveFunction(myObject);
}
return (string)_resourceDescriptionCache[key];

使用单个 UTF32 字符作为潜在大缓存的键感觉很奇怪。

4

3 回答 3

2

那要看。

在许多情况下,使用 GetHashCode() 可能会导致不正确的行为:

哈希码用于在基于哈希表的集合中进行高效插入和查找。哈希码不是永久值。为此原因:

  • 不要序列化哈希码值或将它们存储在数据库中。
  • 不要使用哈希码作为键从键控集合中检索对象。
  • 不要跨应用程序域或进程发送哈希码。在某些情况下,可以在每个进程或每个应用程序域的基础上计算哈希码。

http://msdn.microsoft.com/en-us/library/system.object.getashcode.aspx

如果内存缓存发生(或将来可能发生)在与调用它的代码不同的进程或应用程序域中,则第 3 个条件失败。

使用单个 UTF32 字符作为潜在大缓存的键感觉很奇怪。

如果你缓存了足够多的东西,由于生日问题,32 位散列的冲突率可能会高得令人不安。

在缓存数以千万计的东西时,我使用了一个名为City Hash(由 Google 创建,开源)的 64 位哈希,并取得了很好的成功。您也可以使用 Guid,尽管与 64 位哈希相比,GUID 用于维护密钥的内存是 64 位哈希的两倍。

于 2014-04-21T18:29:28.327 回答
1

哈希码可能会发生冲突。return 0;是一个有效的实现GetHashCode。多个键将共享一个缓存槽,这不是您想要的……您会混淆对象。

如果您的代码无法使用,return 0;因为GetHashCode您的代码的实现已损坏。

选择更好的缓存键。

于 2014-04-21T18:54:56.320 回答
-1

The memory cache is backed by the normal C# Dictionary. It really isn't much different, other than the fact that it provides expiration

The chances of a collision are 2^32, which is the size of an integer. Even if you do manage to get a collision, the dictionary has safety measures around that (by using the Equals on a collision)

Edit: The key collisions are only handled when a dictionary is given the unaltered key (ex: Dictionary()). In this case, since the MemoryCache uses strings, theres no collision detection.

于 2014-04-21T18:31:23.653 回答