【问题标题】:Complexity of String.GetHashCode() [duplicate]String.GetHashCode() 的复杂性 [重复]
【发布时间】:2012-07-18 20:40:09
【问题描述】:

可能重复:
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 实现的哈希码已经从构建时间计算出来?

【问题讨论】:

  • 除了有点复杂和4字节的内存,什么都没有。
  • 我觉得这个问题太好了,直到今天都没有被问到。不幸的是,在我写它的时候它从来没有出现过……我只是投票决定关闭它。

标签: .net string hash


【解决方案1】:

好问题!

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 对象。在绝大多数情况下,这不值得付出努力。如果您碰巧是个例外情况,我仅将这个想法作为考虑因素。

【讨论】:

    【解决方案2】:

    只有假设每次创建字符串时(几乎)都使用哈希码,这才有意义。如果你不使用哈希码,你仍然会付出计算的代价。我同意你的实习字符串,这实际上可能是值得的,只要它可以作为实习的一部分完成。

    【讨论】:

    • 让计算变得懒惰很容易。
    • @CodesInChaos 是的,但这不是 OP 的建议,我的回答是在问题的范围内
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2013-09-23
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      • 2022-08-12
      • 2023-03-25
      相关资源
      最近更新 更多