In .NET System.Object.GetHashCode
method is used in a lot of places, throughout the .NET base class libraries. Especially when finding items in a collection fast or to determine equality. Is there a standard algorithm/ best practice on how to implement the GetHashCode
override for my custom classes so I don't degrade performance?
相关问题
- Generic Generics in Managed C++
- How to Debug/Register a Permanent WMI Event Which
- 'System.Threading.ThreadAbortException' in
- Bulk update SQL Server C#
- Should I use static function in c# where many call
In most cases where Equals() compares multiple fields it doesn't really matter if your GetHash() hashes on one field or on many. You just have to make sure that calculating the hash is really cheap (No allocations, please) and fast (No heavy computations and certainly no database connections) and provides a good distribution.
The heavy lifting should be part of the Equals() method; the hash should be a very cheap operation to enable calling Equals() on as few items as possible.
And one final tip: Don't rely on GetHashCode() being stable over multiple aplication runs. Many .Net types don't guarantee their hash codes to stay the same after a restart, so you should only use the value of GetHashCode() for in memory data structures.
Microsoft lead for several way of hashing...
I can guess that for multiple big int you can use this:
And same for multi-type: all converted first to
int
usingGetHashCode()
then the int values will be xor'ed and the result is your hash.For those who use hash as ID (I mean an unique value), hash is naturally limited to a number of digits, I think it was 5 bytes for hashing algorithm, at least MD5.
You may turn multiple values to a hashed value and some of them be same, so don't use it as an identifier. (maybe some day I am going to use your component)
Here is my simplistic approach. I am using the classic builder pattern for this. It is typesafe (no boxing/unboxing) and also compatbile with .NET 2.0 (no extension methods etc.).
It is used like this:
And here is the acutal builder class:
As of https://github.com/dotnet/coreclr/pull/14863, there is a new way to generate hash codes that is super simple! Just write
This will generate a quality hash code without you having to worry about the implementation details.
I have a Hashing class in Helper library that I use it for this purpose.
Then, simply you can use it as:
I didn't assess its performance, so any feedback is welcomed.
Here's my helper class using Jon Skeet's implementation.
Usage:
If you want to avoid writing an extension method for System.Int32:
It's still generic, it still avoids any heap allocation and it's used exactly the same way:
Update after Martin's comment:
obj != null
caused boxing so I switched to the default comparer.Edit (May 2018):
EqualityComparer<T>.Default
getter is now a JIT intrinsic - the pull request is mentioned by Stephen Toub in this blog post.