Take a look at the following code:
var sw = new Stopwatch(); sw.Start(); Enumerable.Range(0, 3).SelectMany((i) => Enumerable.Range(0, 50000)).OrderBy(i => i).ToList(); Console.WriteLine(sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); Enumerable.Range(0, 2).SelectMany((i) => Enumerable.Range(0, 50000)).OrderBy(i => i).ToList(); Console.WriteLine(sw.ElapsedMilliseconds); sw.Reset();
Line 4 is saying:
Generate a list which looks like 0,1,2..49999,0,1,2..49999,0,1,2..49999
Then Sort it.
While Line 9 is saying:
Generate a list which looks like 0,1,2..49999,0,1,2..49999
Then Sort it.
If you run this program you will see that line 4 executes ( depending on your machine) in less than a second while line 8 executes in around 30 seconds. This may jump out as really strange at first since you are sorting less numbers in line 4. But that isn’t the issue in this scenario. The issue is the sorting algorithm.
Underneath the covers the OrderBy function is using a version of QuickSort. The version of quicksort used always chooses the middle element of the list as the pivot position. Since both left and right lists will always be sorted we hit the worst case of this quicksort algorithm which is O(n^2).