From 673ed336f00ba6ba5ce37e01792934c39b7641c3 Mon Sep 17 00:00:00 2001 From: Peter Smulovics Date: Thu, 20 Apr 2017 18:46:39 -0400 Subject: [PATCH] Fixing Delegate's hash code's distribution (dotnet/coreclr#11019) Delegate's GetHashCode just returns the hash code of the delegate type. For a scenario where delegates are used as keys in a dictionary, this leads to obvious performance problems. We should look at coming up with a better GetHashCode that properly factors in the target object and method, in all of the various forms a delegate can take. Commit migrated from https://github.com/dotnet/coreclr/commit/eb2d44e166f05e1d3da06925c39289bd2c4446a8 --- src/coreclr/src/mscorlib/src/System/Delegate.cs | 5 ++++- .../src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/mscorlib/src/System/Delegate.cs b/src/coreclr/src/mscorlib/src/System/Delegate.cs index de0ff65..75ec57a 100644 --- a/src/coreclr/src/mscorlib/src/System/Delegate.cs +++ b/src/coreclr/src/mscorlib/src/System/Delegate.cs @@ -179,7 +179,10 @@ namespace System else return unchecked((int)((long)this._methodPtrAux)); */ - return GetType().GetHashCode(); + if (_methodPtrAux.IsNull()) + return ( _target != null ? RuntimeHelpers.GetHashCode(_target) * 33 : 0) + GetType().GetHashCode(); + else + return GetType().GetHashCode(); } public static Delegate Combine(Delegate a, Delegate b) diff --git a/src/coreclr/tests/src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs b/src/coreclr/tests/src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs index f2c5c51..05ba362 100644 --- a/src/coreclr/tests/src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs +++ b/src/coreclr/tests/src/CoreMangLib/cti/system/delegate/delegategethashcode1.cs @@ -218,7 +218,7 @@ namespace DelegateTest { bool retVal = true; - TestLibrary.TestFramework.BeginScenario("PosTest7: Use the different instance's same instance method to create two delegate which delegate object is the same,their hashcode is equal"); + TestLibrary.TestFramework.BeginScenario("PosTest7: Use the different instance's same instance method to create two delegate which delegate object is the same, their hashcode is different"); try { @@ -226,7 +226,7 @@ namespace DelegateTest booldelegate workDelegate = new booldelegate(new TestClass(1).StartWork_Bool); booldelegate workDelegate1 = new booldelegate(new TestClass1(2).StartWork_Bool ); - if (workDelegate.GetHashCode()!=workDelegate1.GetHashCode()) + if (workDelegate.GetHashCode()==workDelegate1.GetHashCode()) { TestLibrary.TestFramework.LogError("013", "HashCode is not excepted "); retVal = false; -- 2.7.4