Repository navigation
Speed up RuntimeType.GetHashCode - #134783
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3ed54863-8a13-437b-aa0a-a6f356b253ed
This comment was marked as outdated.
This comment was marked as outdated.
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @dotnet/area-system-runtime |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3ed54863-8a13-437b-aa0a-a6f356b253ed
|
@EgorBot -windows_intel -linux_amd -osx_arm -linux_arm using System;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Bench).Assembly).Run(args);
public class Bench {
private readonly Dictionary<Type, int> _dictionary = new() { [typeof(string)] = 42 };
[Benchmark]
public int Lookup() => _dictionary[typeof(string)];
}Note Benchmark generated with GitHub Copilot. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The performance claim lacks measurements, and the new hash paths lack targeted tests.
Review effort: Balanced
Findings: 1
Open (2)
What changed in this PR
Optimizes CoreCLR RuntimeType.GetHashCode while retaining existing behavior for Mono and COM identity types.
Changes:
- Uses CoreCLR type handles for hashing.
- Preserves identity hashing for CLSID-backed COM types.
- Moves Mono’s existing identity hash implementation to its runtime-specific file.
| File | Description |
|---|---|
System/RuntimeType.Mono.cs |
Retains Mono identity hashing. |
System/RuntimeType.cs |
Removes the shared implementation. |
System/RuntimeType.CoreCLR.cs |
Adds handle-based hashing with a COM exception. |
This comment was marked as outdated.
This comment was marked as outdated.
For unconstrained T, 'obj?.GetHashCode()' makes Roslyn emit ldarga/ldloca with a byref merge, which makes the JIT address-expose both locals after inlining and blocks devirtualization and constant folding (e.g. Dictionary<Type, T> lookups with typeof(X) keys). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 033db876-d232-451a-94ab-ed732694508a
|
@EgorBot -windows_intel -linux_amd -osx_arm -linux_arm -profiler using System;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Bench).Assembly).Run(args);
public class Bench {
private readonly Dictionary<Type, int> _dictionary = new() { [typeof(string)] = 42 };
[Benchmark]
public int Lookup() => _dictionary[typeof(string)];
}Note Benchmark generated with GitHub Copilot. |
|
PTAL @jkotas, it seems to speed up Mainly because JIT constant folds the entire thing into 32bit constant (e.g. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 033db876-d232-451a-94ab-ed732694508a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 033db876-d232-451a-94ab-ed732694508a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 033db876-d232-451a-94ab-ed732694508a
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 033db876-d232-451a-94ab-ed732694508a



Use mixed type-handle hashes in CoreCLR, preserving COM identity hashing (Windows only).
Results
Win-x64:
osx-arm64: