Nehmen wir an, Sie haben eine Point
Datenstruktur, die durch eine Variable x
und y
dargestellt wird. Ohne die Bitverschiebung wäre der Wert des Hash-Codes für 1
, und der Hash-Code für (0,1)
wäre auch 1
. Jetzt tun die gleiche Sache mit der Bitverschiebung, für (1,0)
wir einen Hash-Code von 1
bekommen, aber für (0,1)
wir jetzt einen Hash-Code von 4
Was die Bitverschiebung bietet erhalten, wenn Sie die gleichen Eingaben aber in eine haben andere Reihenfolge, die Sie verschiedene Hash-Codes erhalten möchten, auf diese Weise (1,0)
und (0,1)
nicht am Ende in den gleichen Hash-Bucket fallen und Ihre Hashset/Wörterbuch Leistung verschlechtern.
Normalerweise würden Sie einen viel größeren Offset als nur zweimal zweimal verschieben. Bitshifting bewirkt auch, dass Daten abgeschnitten werden, wenn Hash-Codes in der Nähe von Int32.MaxValue
behandelt werden. Hier ist das Muster, das normalerweise I
public override int GetHashCode()
{
unchecked
{
var hashCode = X;
hashCode = (hashCode*397)^Y;
hashCode = (hashCode*397)^Z;
return hashCode;
}
}
verwenden (dies ist die Standardimplementierung, die mit ReSharper der „Insert Vergleichsmethode“ Feature kommt. Um weitere Felder hinzufügen, die Sie gerade hashCode = (hashCode*397)^XXXXXXX
weiterhin tun)
Durch die Verwendung von *
mit unchecked
anstelle von <<
überläuft jeder Wert, der größer als Int32.MaxValue
ist, einfach ohne Fehler.
Haben Sie versucht, irgendwelche Forschung zu dem Thema/Google-Suche auf dem folgenden 'C# tut Bitverschiebungsoperation macht die Hash-Werte besser? Ich würde zuerst dort beginnen – MethodMan
Sie würden in der Regel eine oder mehrere (nicht alle) der Werte in einem Hash-Code verschieben möchten, so dass Sie einen Hash-Code erstellen können, der mehr verteilt ist. Wenn Sie zum Beispiel in Ihrem ersten Beispiel keinen der Werte verschoben haben, dann wäre der Hash-Code für x = 1, y = 2 gleich wie x = 2, y = 1; aber Sie möchten einen anderen Hash-Code, um anzuzeigen, dass dies tatsächlich zwei verschiedene Werte des Objekts sind. –