Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Take advantage of algorihmic differences between first-from-ordered and ordered. #14867

@JonHanna

Description

@JonHanna

The fact of something being ordered can have implications for subsequent operations.

The ordering Linq methods (OrderBy, ThenBy, etc.) operate first in O(1) time and space to make a promise of a subsequent O(n log n) sort in O(n) space. In many case though the following operation does not need all of the promised operation.

.OrderBy(λ).First(), .OrderBy(λ).First(λ), and so on request that a sequence be sorted (O(n log n) time/O(n) space) and then the first element taken (O(1) time and space) which is in total an O(n log n) time/O(n) space operation. However, it is reducible to the O(n) time/O(1) space operation of identifying just the item in question which can be done in O(n) time and O(1) space.

As First, Last and their variants are particularly common with ordered sequences (in some cases not having any meaning without an order), I think this would be a worth-while optimisation.

There are other optimisations available, such as all aggregate operations (Sum etc.) could be moved from O(n log n) time to O(n) time simply by extracting the source and ignoring the ordering, this may not be as common a case as to make it worthwhile. One could argue that the user should have not put the ordering in there in the first place, and while the cost of checking for an ordered source is slightly, it's not worth paying it on all aggregate operations to benefit a flawed case.

Reverse is somewhere in the middle. It's reasonable to expect someone might construct an ordered sequence and then Reverse in some cases. It's got subtleties (one cannot simply reverse all OrderBy to OrderByDescending and vice-versa because OrderBy is documented as performing stable ordering in linq-2-objects and therefore reversed must have reverse source ordering on equivalent items) but wouldn't be hard, but it's less clear whether the pay off would be worth it.

In the more useful cases of First etc. there is a fly in the ointment in that this would affect the number of times both key selectors for ordering and predicates for First etc. were called. As per #14842 this means side effects on Funcs would be affected, though perhaps in a way that was less predictable to the user than with that issue anyway.

As such, changing the behaviour of First in this case would require either a decision in favour of the change that issue would allow for, or a decision that this case was less harmed by such changing side-effects.

In summary. I propose that OrderBy(…).First(…) and its cousins be optimised, and the trade-offs of optimising OrderBy(…).Reverse() be considered.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions