Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Change ArraySortHelper to use Comparison<T>#8504

Merged
jkotas merged 2 commits intodotnet:masterfrom
mikedn:sort-comparison
Dec 7, 2016
Merged

Change ArraySortHelper to use Comparison<T>#8504
jkotas merged 2 commits intodotnet:masterfrom
mikedn:sort-comparison

Conversation

@mikedn
Copy link

@mikedn mikedn commented Dec 7, 2016

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.

Fixes #8481

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.

IntrospectiveSort(keys, index, length, comparer);
#else
if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkotas @AlexGhiondea BinaryCompatibility has been removed from this repository but there are still references to it in ifdefed out code. Should such code be removed as well? We'd get rid of DepthLimitedQuickSort which isn't used anywhere in CoreCLR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is fine to delete the code under #if !FEATURE_CORECLR. https://github.com/dotnet/coreclr/issues/972#issuecomment-257633318

@jkotas
Copy link
Member

jkotas commented Dec 7, 2016

Looks pretty good to me.

These are never used in CoreCLR
@mikedn
Copy link
Author

mikedn commented Dec 7, 2016

I suspect that there's more that can be done about the default comparer case, e.g. caching the delegate built from the default comparer. I doubt it's worth it and can be done in a separate PR anyway.

I didn't modify ArraySortHelper<T>.BinarySearch because BinarySearch doesn't currently offer a Comparison<T> overload. Add allocating a delegate every time you search using a comparer doesn't sound like good compromise.

I also didn't modify ArraySortHelper<TKey, TValue>. The key/value Sort overloads also don't offer Comparison<T> versions and in my experience they are rarely used.

@mikedn mikedn changed the title [WIP] Change ArraySortHelper to use Comparison<T> Change ArraySortHelper to use Comparison<T> Dec 7, 2016
@jkotas
Copy link
Member

jkotas commented Dec 7, 2016

Thanks!

@jkotas jkotas merged commit 2d888b5 into dotnet:master Dec 7, 2016
@jkotas
Copy link
Member

jkotas commented Dec 7, 2016

Would you mind porting the change to CoreRT as well?

@mikedn mikedn deleted the sort-comparison branch April 10, 2017 05:43
@karelz karelz modified the milestone: 2.0.0 Aug 28, 2017
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Change ArraySortHelper to use Comparison<T>

Commit migrated from dotnet/coreclr@2d888b5
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants