簡単なGetHashCode()の実装例とパフォーマンス比較
追記:Visual Studio 2017・ReSharperで自動生成できるので、もはや自動生成一択。
Generate C# Equals and GetHashCode Method Overrides - Visual Studio | Microsoft Docs
IEquatable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [Config(typeof(BenchmarkConfig))] | |
| public class GetHashCodeBenchmark | |
| { | |
| private int m_value = 10; | |
| private EmptyClass m_instance = new EmptyClass(); | |
| [Benchmark] | |
| public int AnonymousType_GetHashCode() | |
| { | |
| return new { m_value, m_instance }.GetHashCode(); | |
| } | |
| [Benchmark] | |
| public int ValueTuple_GetHashCode() | |
| { | |
| return (m_value, m_instance).GetHashCode(); | |
| } | |
| [Benchmark(Baseline = true)] | |
| public int Combine_GetHashCode() | |
| { | |
| return Combine(m_value.GetHashCode(), m_instance.GetHashCode()); | |
| } | |
| // https://github.com/dotnet/corefx/blob/master/src/Common/src/System/Numerics/Hashing/HashHelpers.cs | |
| private static int Combine(int h1, int h2) | |
| { | |
| uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27); | |
| return ((int)rol5 + h1) ^ h2; | |
| } | |
| } | |
| public class EmptyClass | |
| { | |
| } |
| Method | Mean | Error | StdDev | Scaled | ScaledSD | Gen 0 | Allocated |
|---|---|---|---|---|---|---|---|
| AnonymousType_GetHashCode | 23.264 ns | 1.9239 ns | 0.1087 ns | 6.18 | 0.02 | 0.0051 | 16 B |
| ValueTuple_GetHashCode | 15.350 ns | 0.1826 ns | 0.0103 ns | 4.08 | 0.00 | - | 0 B |
| Combine_GetHashCode | 3.764 ns | 0.0444 ns | 0.0025 ns | 1.00 | 0.00 | - | 0 B |
ValueTuple使うか直書きするかになるが、覚えやすさ・読みやすさ・間違えにくさを考えてValueTupleが使いやすいだろう。このアルゴリズムはModified Bernsteinというらしい*2。