String.GetHashCode()的复杂性

时间:2012-07-18 20:40:10

标签: .net string hash

  

可能重复:
  Why might a System.String object not cache its hash code?

我一直认为,鉴于.Net字符串是不可变的,String.GetHashCode()不必在每次调用时计算哈希值 - 如果字符不会改变,则哈希值对于给定值是常量System.String的一个例子,我天真地想; String.GetHashCode()可能有O(1)的复杂性。

Reverse engineering it打破了这个假设。

当然,哈希码并不是常量and so on,但是什么可以阻止String实现已经从构建时间计算出哈希码?

3 个答案:

答案 0 :(得分:2)

好问题!

I asked the same thing a while back.

基本上,这是速度/内存的权衡。缓存字符串哈希码的好处可以说是每个字符串对象的开销超过需要分配另外32位内存的开销。当您考虑程序中可能存在的大量字符串与您关心的哈希码的数字(可能是因为您将它们用作键)时,这是有道理的。

后一个数字在某些程序中可能很大,但也可能很小。在很多情况下甚至可能为零。

如果在某些情况下性能是极度关注,那么可能会考虑编写自己的包装程序来缓存其哈希代码:

public class StringKey
{
    string value;
    int hashCode;

    public StringKey(string value)
    {
        this.value = value;
        this.hashCode = value.GetHashCode();
    }

    public override int GetHashCode()
    {
        return this.hashCode;
    }

    public override string ToString()
    {
        return this.value;
    }

    // Plus all the other stuff you'd want to include here,
    // e.g., Equals, CompareTo, etc.
}

当然,为了从中获得任何好处,您仍然需要非常小心地在整个程序中重复使用这些StringKey对象。在绝大多数情况下,这不值得付出努力;如果碰巧是一个例外的案例,我只是将这个想法包括在内。

答案 1 :(得分:0)

只有在每次创建字符串时(几乎)都使用哈希码时,这才有意义。如果您不使用哈希码,您仍然需要支付计算费用。我授予你实习词,这可能实际上是值得的,只要它可以作为实习的一部分完成。

答案 2 :(得分:0)

我认为问题在于存储哈希码的位置。对字符串存储执行了大量优化,因为添加更多存储要求会过于复杂。