This is purely for my own knowledge, if I were going to write the code I would just use .Max()
.
At first thought .Max()
only has to do a single pass through numbers
to find the max, while the second way has to sort the entire thing enumerable then find the first one. So it's O(n)
vs O(n lg n)
. But then I was thinking maybe it knows it only needs the highest and just grabs it.
Question: Is LINQ and/or the compiler smart enough to figure out that it doesn't need to sort the entire enumerable and boils the code down to essentially the same as .Max()? Is there a quantifiable way to find out?
IEnumerable<int> numbers = Enumerable.Range(1, 1000);
int max = numbers.Max();
int max2 = numbers.OrderByDescending(x => x).First();
It appears that OrderedEnumerable is now smart enough to figure out that it doesn't need to sort the list for First and Last().
Note the code at around line 223, TryGetFirst() https://github.com/dotnet/corefx/blob/ed0ee133ac49cee86f10ca4692b1d72e337bc012/src/System.Linq/src/System/Linq/OrderedEnumerable.cs
.Max()
is O(n), while your OrderByDescending
solution isn't - depending on the sort, it's probably O(nlog(n)).
I obviously haven't dug inside the compiler to know, but what you're asking for (an optimization that realizes sort then grab only one item is the same as .max) is rather a lot from a compiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With