66

Evidently LINQ's "OrderBy" had originally been specified as unstable, but by the time of Orca it was specified as stable. Not all documentation has been updated accordingly - consider these links:

But if LINQ's OrderBy is now "stable," then it means it is not using a quicksort (which is inherently unstable) even though some documentation (e.g. Troy's book) says it is. So my question is: if not quicksort, then what is the actual algorithm LINQ's orderBy is using?

Community
  • 1
  • 1
Brent Arias
  • 29,277
  • 40
  • 133
  • 234
  • 2
    Stictly, Linq's `OrderBy` is not specified for stability. `Enumerable.OrderBy` is specified as stable, other providers are free to also offer that promise but may not. Doing so may be impossible or very expensive (consider the impact it would have on parallelisation in terms of p-linq for example) or relatively cheap, which is a big influence on what providers will do. – Jon Hanna Dec 10 '16 at 02:21
  • A very related post [here](https://stackoverflow.com/q/148074/465053). – RBT Aug 10 '17 at 01:43
  • 2
    would it be bad to tag this [c#]? or at least [.net]? I missed this question because I begin all my queries with [c#] (unless I happen to be doing javascript that day)... – NH. Dec 12 '18 at 23:32

4 Answers4

70

For LINQ to Objects, it's a stable quicksort that is used. For any other kind of LINQ, it's left to the underlying implementation.

Jb Evain
  • 17,319
  • 2
  • 67
  • 67
  • If I have an object referenced as only `IEnumerable` how does Linq know if it's Linq-to-Objects or something else? – Dai Aug 04 '16 at 10:47
  • IEnumerable is always Linq to objects (vs IQueryable which is Linq to whatever else) – John Mar 14 '17 at 15:01
  • 2
    @Dai IEnumerable is an interface, so it actually depends of what type has the underlying collection (I dont agree with @John). For instance, List implements IEnumerable, and you could have a List declared as IEnumerable. If you perform an order by on this list, the Linq-to-objects provider is used. On the other hand. DbSet also implements IEnumerable. If you perform an order by on this DbSet, even if it is declared as an IEnumerable, Linq-to-sql provider will be used. If you wanted to use linq-to-objects on a dbset, you could do dbset.AsEnumerable().OrderBy(lambda) – Daniel García Rubio Oct 06 '17 at 09:49
  • @DanielGarcíaRubio DbSet does not directly implement IEnumerable, it implements IQueryable, which in turn always implements IEnumerable. So i dont completely understand why you do not agree with John, as what he said is correct. – Alexei Sosin Jul 24 '19 at 04:57
42

Boot up reflector, open to System.Linq.EnumerableSorter reveals that Linq2Objects uses the quick sort

LorenVS
  • 12,597
  • 10
  • 47
  • 54
  • +1 for looking it up. But a simple test shows no n^2 growth in time consumption as elements number of reverse sorted List of int increases, as it should be according to en.wikipedia.org/wiki/Quicksort I tried 1k and 1M elements worst-case - time consumption increased only about 50 times – EvAlex Mar 21 '12 at 07:23
  • @EvAlex Quicksort doesn't run in quadratic time. Well, it can, but that's the upper bound and rare. If it were theta(n**2) everyone would just use mergesort. – Casey May 16 '14 at 19:44
  • 12
    Now .NET core is opened to everyone :) Why don't you have a closer look? http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,1395017e067e5a34 – Joon Hong Nov 27 '14 at 05:47
15

Quicksort is used, but the reason why it is stable is because the indices of each pair of elements are compared if all the keys test equal.

In other words, you can make any quicksort stable by including in the comparator function a comparison of the original indices of the two elements as a fallback.

Source: http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,1395017e067e5a34

Wesner Moise
  • 261
  • 2
  • 3
  • Have been looking for a while for the open source link, thanks – Rami Alshareef Apr 22 '18 at 15:19
  • In theory, you could stabilise any sorting algorithm by including the original indices in the comparator. The challenge is figuring out the best data structure to use to keep track of these original indices. – Stewart Jun 06 '19 at 16:24
3

I am under the understanding that OrderBy gets translated into SQL that performs the sort on the Database. At least in the case of LINQ to SQL

John Weldon
  • 39,849
  • 11
  • 94
  • 127
  • 14
    Yes, but that's only true for Linq to SQL and other database Linq providers. Linq is not just an ORM... (Linq to Objects, Linq to XML...) – Thomas Levesque May 07 '10 at 23:20