2

重複の可能性:
System.Stringオブジェクトがハッシュコードをキャッシュしないのはなぜですか?

String.GetHashCode().Net文字列は不変であるため、呼び出されるたびにハッシュを計算する必要はないと常に思っていました。文字が変更されない場合、ハッシュはSystem.Stringの特定のインスタンスに対して一定です。考え; String.GetHashCode()O(1)の複雑さを持つ可能性があります。

リバースエンジニアリングは、この仮定を打ち砕きました。

もちろん、ハッシュコードは一定などを意味するものではありませんが、文字列の実装で、たとえば構築時間からハッシュコードがすでに計算されているのを防ぐにはどうすればよいでしょうか。

4

3 に答える 3

2

良い質問!

しばらく前に同じことを聞いた。

基本的に、これは速度とメモリのトレードオフです。文字列ハッシュコードをキャッシュすることの利点は、おそらく、さらに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基本的にプログラム全体でこれらのオブジェクトをどこでも再利用するように非常に注意する必要があります。ほとんどの場合、これは努力する価値がありません。私は、あなたがたまたま例外的なケースである場合に考慮すべきこととしてのみ、このアイデアを含めました。

于 2012-07-18T20:44:05.673 に答える
0

これは、文字列を作成するたびに(ほぼ)ハッシュコードが使用されると想定した場合にのみ意味があります。ハッシュコードを使用しない場合でも、計算のペナルティを支払うことになります。インターンされたストリングについては、インターンの一部として実行できる限り、これは実際には価値のあるものである可能性があります。

于 2012-07-18T20:44:53.783 に答える
0

問題はハッシュコードをどこに保存するかだと思います。文字列ストレージでは非常に多くの最適化が実行されているため、ストレージ要件を追加すると非常に複雑になります。

于 2012-07-18T20:45:41.507 に答える