Closed ltrzesniewski closed 2 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to this area: @dotnet/area-system-collections See info in area-owners.md if you want to be subscribed.
Author: | ltrzesniewski |
---|---|
Assignees: | - |
Labels: | `area-System.Collections`, `tenet-performance`, `untriaged` |
Milestone: | - |
I'll take a look, the problem that getDefaultComparerClassHelper
currently only devirtualizes Nullable<>
for T : IEquatable<T>
https://github.com/dotnet/runtime/blob/7bfc61b970e28f94782ef7c0cbcbbbc94ef9f5eb/src/coreclr/vm/jitinterface.cpp#L8822-L8827
so we might want to introduce a NullableEnumComparer
Tagging subscribers to this area: @JulieLeeMSFT See info in area-owners.md if you want to be subscribed.
Author: | ltrzesniewski |
---|---|
Assignees: | - |
Labels: | `tenet-performance`, `area-CodeGen-coreclr` |
Milestone: | - |
Thanks @EgorBo! 🙂
Description
EqualityComparer<TEnum?>.Default
(whenT
is a nullable enum) is resolved toObjectEqualityComparer<TEnum?>
, which boxes the enum when performing equality comparison. This causes an unnecessary allocation.Here is a reproduction:
This results in:
If you replace
DayOfWeek?
withDayOfWeek
, or if you use a type such asint?
instead, the code will printAllocation-free
.Configuration
I reproduced this on .NET 6 and on .NET 7 preview 2 on Windows x64, but this should be independent of the OS and architecture.
Regression?
This is not a regression. It also reproduces on .NET Framework 4.8.
Analysis
This is roughly due to the fact that
ComparerHelpers.CreateDefaultEqualityComparer
special-cases bothNullable<T>
and enums, but does not special-case nullable enums. This code path ends up usingObjectEqualityComparer<T>
.I'm willing to provide a PR to fix this if you'd like.