2012-07-18 50 views
2

可能重复:
Why might a System.String object not cache its hash code?复杂String.GetHashCode的()

我一直认为,考虑到净字符串是不可改变的,String.GetHashCode()没有计算哈希每次调用时 - 如果字符不会改变,散列对于给定的System.String实例是不变的,我天真地想; String.GetHashCode()可能有O(1)的复杂性。

Reverse engineering it粉碎了这个假设。

当然,散列码并不意味着恒定为and so on,但是可以防止String实现具有已经从构建时间计算出来的散列码?

+0

除了一点复杂性和4个字节的内存,什么也没有。 – CodesInChaos 2012-07-18 20:44:04

+0

我感觉到这个问题太好了,至今仍未得到解决。不幸的是,当我写它时,它从来没有出现过......我只是投票结束了这个。 – Humberto 2012-07-18 20:47:18

回答

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. 
} 

要获得任何好处了这一点,当然,你仍然需要非常小心地在整个程序中重用这些对象。在绝大多数情况下,这是不值得的;如果你碰巧是一个特殊情况,我只是将这个想法包括在内。

0

如果您认为每次创建字符串时都使用了散列码(几乎),那么这样做才有意义。如果你不使用哈希码,你仍然会支付计算的代价。我向你授予实习字符串,这可能实际上是值得的,只要它可以作为实习的一部分来完成。

+0

让懒惰计算会很容易。 – CodesInChaos 2012-07-18 20:45:57

+0

@CodesInChaos是的,但这不是OP的建议,我的答案是在问题的上下文中 – 2012-07-19 06:59:00

0

我认为问题是在哪里存储哈希码。在字符串存储上执行的优化太多了,因为添加更多的存储需求会过于复杂。