如何确定缓存hashCode()结果是否合适?

4

假设我有一个不可变的类,并编写了一个GetHashCode()函数,那么如何知道缓存哈希结果是否有益,在大多数情况下是否明智?

考虑到GetHashCode()计算已经针对原始类型和字符串值进行了优化,那么这是我应该考虑的吗?

我的典型GetHashCode()可能看起来像以下代码:

//C#
public override int GetHashCode() {
    int hash = 13;
    hash = 13 * hash + IntValue;
    hash = 13 * hash + (StringValue1 == null ? 0 : StringValue1.GetHashCode());
    hash = 13 * hash + (StringValue2 == null ? 0 : StringValue2.GetHashCode());
    return hash;
}

关于在何种情况下使用哈希表,我的想法如下:

  1. 如果哈希表或字典的键(key)是必须要使用的。
  2. 如果该哈希表在其生命周期内有许多查找操作。

6
当分析显示GetHashCode占用了大量时间时。 - porges
3
  1. 第一点似乎与本题无关。
  2. 第二点应在性能分析器中展现。
- H H
你可以使用 int hash = IntValue; 来简化第一行。在Java中,String.hashCode()已经被缓存了,所以在这种情况下可能没有你想象的那么有价值。 - Peter Lawrey
谢谢大家的评论,我可能过早地提出了这个问题,希望能听取同行对这个主题的想法。 - Brett Ryan
1个回答

4
你的观点“1”仅仅是定义了何时应该实现GetHashCode()(和匹配的Equals),在这种情况下,你应该(“2”)期望它查询了一个适度数量的次数。然而,关键在于性能分析,或者先前已知的情况。例如,如果你的哈希值实际上是对一个相对较大的内部数组进行哈希处理,则很可能值得缓存。在这种情况下,我会懒惰地缓存它(可能作为一个int?),除非我知道它将被用作一个键(总是),在这种情况下,我可能会急切地预先计算它。
然而,在大多数情况下,每次都按需计算即可。

谢谢Marc,我在提问之前应该更多地考虑问题。在某些情况下,我已经缓存了一些可能具有不可变数组的内容,并按照您的建议使用了int? - Brett Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接