Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Max() vs OrderByDescending().First()

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();
like image 276
jb. Avatar asked Apr 24 '12 02:04

jb.


2 Answers

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

like image 112
Anthony Wieser Avatar answered Oct 12 '22 09:10

Anthony Wieser


.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.

like image 31
Mahmoud Al-Qudsi Avatar answered Oct 12 '22 11:10

Mahmoud Al-Qudsi