It is clear that any collisions in the Word.GetHashCode()
implementation would result in a collision in (int) Word.GetHashCode() * 7
implementation, because multiplying identical numbers produce identical results.
A more interesting question is if non-colliding hash codes from the first implementation would result in collisions within the second implementation. It turns out that the answer is "no", because the range of int
and 7
are mutually prime numbers. Hence, multiplication produces a unique mapping after dropping the overflow.
You can run a small test with two-byte hash codes to see what happens:
const int Max = 1<<16;
var count = new int[Max];
for (int i = 0 ; i != Max ; i++) {
count[(i * 7) & (Max-1)]++;
}
var notOne = 0;
for (int i = 0 ; i != Max ; i++) {
if (count[i] != 1) {
notOne++;
}
}
Console.WriteLine("Count of duplicate mappings found: {0}", notOne);
This program maps i
, the hash code value, to 7 * i
modulo 216, and verifies that each number from the range is produced exactly once.
Count of duplicate mappings found: 0
Demo.
If you replace 7
with an even number, the result is going to be very different. Now multiple hash codes from the original set would be mapped to a single hash code in the target set. You can understand this intuitively if you recall that multiplying by an even number always makes the least significant bit to be zero. Hence, some information is lost, depending on how many times the even number can be divided by two.
which one is better?
There is no difference.
Note: The above assumes that you are ignoring integer overflow.