The history why is long, but the problem is simple. Having 3 strings I need to cache the matching value. To have a fast cache I use the following code:
public int keygen(string a, string b, string c)
{
var x = a + "@@" + b + "@@" + c;
var hash = x.GetHashCode();
return hash;
}
(Note that string a
,b
,c
does not contain the code "@@"
)
The cache it self is just a Dictionary<int, object>
I know there is a risk that the hash key might be non unique, but except this:
Does anyone know a faster way to make an int key? (in C#) This operation takes ~15% of total CPU time and this is a long running app.
I have tried a couple of implementations but failed to find any faster.
Instead of concatenating strings (which creates new strings) you could use XOR
or even better simple maths (credits to J.Skeet):
public int keygen(string a, string b, string c)
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + a == null ? 0 : a.GetHashCode();
hash = hash * 23 + b == null ? 0 : b.GetHashCode();
hash = hash * 23 + c == null ? 0 : c.GetHashCode();
return hash;
}
}
In general it's not necessary to produce unique hashs. But you should minimize collisions.
Another(not as efficient) way is to use an anonymous type which has a builtin support for GetHashCode
:
public int keygen(string a, string b, string c)
{
return new { a, b, c }.GetHashCode();
}
Note that the name, type and order matters for the calculation of the hashcode of an anonymous type.