Change ArraySortHelper to use Comparison<T>#2308
Conversation
The Array/List.Sort overloads that take a Comparison<T> have worse performance than the ones that take a IComparer<T>. That's because sorting is implemented around IComparer<T> and a Comparison<T> needs to be wrapped in a comparer object to be used. At the same time, interface calls are slower than delegate calls so the existing implementation doesn't offer the best performance even when the IComparer<T> based overloads are used. By changing the implementation to use Comparison<T> we avoid interface calls in both cases. When IComparer<T> overloads are used a Comparison<T> delegate is created from IComparer<T>.Compare, that's an extra object allocation but sorting is faster and we avoid having two separate sorting implementations.
|
Hi @mikedn, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution! The agreement was validated by .NET Foundation and real humans are currently evaluating your PR. TTYL, DNFBOT; |
|
@mikedn I'll take a look at the Generics test failing tomorrow. This is unlikely to be a problem in your change. Shared generics are not completely done yet and this is either uncovering a bug or hitting a missing feature in shared generics. |
|
Presumably this is caused by And the compilation exception is: That |
Yup, that's exactly what's going on. Since #2102 is not implemented yet, RyuJIT lands in I'll see if I can cook up something or if I need @sandreenko's help on the RyuJIT side. Sorry for the trouble. |
|
I suppose I can take a look at the JIT side as well if you and @sandreenko have other priorities. |
|
@dotnet-bot test this please |
|
I suppose it's worth asking if such delegate calls have the same perf characteristics they have in the normal CLR. I'm getting the impression that in the current implementation the call will pass through a stub and that more work is needed to avoid this? |
|
You are right - these calls do not have same perf characteristics in CoreRT right now, but we are going to fix that. #2342 is tracking fixing it. It should not prevent this change from going in. |
The Array/List.Sort overloads that take a
Comparison<T>have worse performance than the ones that take aIComparer<T>. That's because sorting is implemented aroundIComparer<T>and aComparison<T>needs to be wrapped in a comparer object to be used.At the same time, interface calls are slower than delegate calls so the existing implementation doesn't offer the best performance even when the
IComparer<T>based overloads are used.By changing the implementation to use
Comparison<T>we avoid interface calls in both cases.When
IComparer<T>overloads are used aComparison<T>delegate is created fromIComparer<T>.Compare, that's an extra object allocation but sorting is faster and we avoid having two separate sorting implementations.Port of dotnet/coreclr#8504