7

の実装Nullable<T>.GetHashCode()は次のとおりです。

public override int GetHashCode()
{
    if (!this.HasValue)
    {
        return 0;
    }
    return this.value.GetHashCode();
}

ただし、基になる値が0のハッシュコードも生成する場合(たとえば、boolをfalseに設定するか、int32を0に設定する)、同じハッシュコードで2つの一般的に発生する異なるオブジェクト状態があります。より良い実装は次のようなものだったと私には思えます。

public override int GetHashCode()
{
    if (!this.HasValue)
    {
        return 0xD523648A; // E.g. some arbitrary 32 bit int with a good mix of set and 
                           // unset bits (also probably a prime number).
    }
    return this.value.GetHashCode();
}
4

4 に答える 4

4

はい、あなたにはポイントがあります。保存するデータを事前に知っていれば、より優れたGetHashCode()実装を作成することは常に可能です。図書館の作家がこれまでに利用できた贅沢ではありません。しかし、はい、ブール値がたくさんある場合はどうなりますか?falseまたは!HasValueのいずれかである場合、デフォルトの実装が問題になります。enumsとintsについても同じですが、ゼロが一般的な値です。

あなたの議論は学術的ですが、実装コストから1万ポイントを差し引いたものを変更すると、自分でそれを行うことはできません。あなたができる最善のことは提案を提出することです、適切なチャネルはユーザー音声サイトです。これを牽引するのは難しいでしょう、幸運を祈ります。

于 2012-11-23T12:19:39.710 に答える
2

最初に、この質問はパフォーマンスに関するものであることに注意してください。ハッシュコードは、正確性のために一意または衝突耐性である必要はありません。ただし、パフォーマンスには役立ちます。

実際には、これがハッシュテーブルの主な価値提案です。実質的に均等に分散されたハッシュコードは、O(1)の動作につながります。

では、実際のアプリケーションで可能な限り最高のパフォーマンスプロファイルにつながる可能性が最も高いハッシュコード定数はどれでしょうか。

確かに、それは一般的なハッシュコード0だからではありません。それは他のタイプにも当てはまります。頻繁に発生する傾向があるため、最悪の候補です。00.GetHashCode() == 00

では、衝突を回避する方法は?わたしの提案:

static readonly int nullableDefaultHashCode = GetRandomInt32();
public override int GetHashCode()
{
    if (!this.HasValue)
        return nullableDefaultHashCode;
    else
        return this.value.GetHashCode();
}

均等に分散され、衝突する可能性が低く、任意の定数を選択するというスタイル上の問題はありません。

として実装GetRandomInt32 できることに注意してくださいreturn 0xD523648A;。それでも。よりも便利ですreturn 0;。しかし、疑似乱数の安価なソースを照会するのがおそらく最善です。

于 2012-11-23T11:45:32.017 に答える
1

結局、Nullable<T>値なしはハッシュコードを返す必要があり、そのハッシュコードは定数でなければなりません。

任意の定数を返すことは、より安全または適切に見えるかもしれません。おそらく、の特定のケース内で見るとさらに安全に見えるかもしれませんNullable<int>が、最終的にはそれだけです:ハッシュ。

そして、カバーできるセット全体Nullable<T>(無限大)の中で、ゼロは他のどの値よりも優れたハッシュコードではありません。

于 2012-11-23T11:40:47.133 に答える
0

私はここでの懸念を理解していません-どのような状況でパフォーマンスが低下しますか?

1つの値の結果に基づいて、ハッシュ関数を貧弱と見なすことができるのはなぜですか。

Typeハッシュの多くの異なる値が同じ結果になると、問題になることがわかりました。しかし、nullが0と同じ値にハッシュされるという事実は重要ではないようです。

私の知る限り、.NETハッシュ関数の最も一般的な使用法は、Hashtable、HashSet、またはDictionaryキーであり、ゼロとnullが同じバケットにあるという事実は、全体的なパフォーマンスにわずかな影響しか与えません。

于 2012-11-23T12:17:22.503 に答える