Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happened to Array.Sort() in .NET 4.0? Is TrySZSort() gone?

I wonder why the following snippet does not give the expected result? It sorts a not too small random array and uses 3 different methods for it. I was expecting the speed to come out as so:

  1. Array.Sort() - fastest by using the native TrySZSort function as I recall from .NET 2.0
  2. Descending sort by using the custom Comparer class
  3. The lambda expression sort.

The Code:

class DescComparer : IComparer<double> {
    // simple comparison 
    // (yes, its not exactly correct ...)
    public int Compare(double x, double y) {
        return (x > y) ? -1 : 1; 
    }
}
static void Main(string[] args) {
    Stopwatch sw = new Stopwatch(); 
    Random rand = new Random(); 
    DescComparer comparer = new DescComparer();
    double[] a = new double[1000000]; 
    for (int r = 0; r < 20; r++) {

        // init array
        for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();  
        sw.Restart();
        Array.Sort(a);
        sw.Stop();
        Console.WriteLine("ascending took: {0} ms ", sw.ElapsedMilliseconds);

        // init array
        for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();
        sw.Restart();
        Array.Sort<double>(a, comparer);
        sw.Stop();
        Console.WriteLine("descending took: {0} ms ", sw.ElapsedMilliseconds);

        // init array
        for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();
        sw.Restart();
        Array.Sort<double>(a, (x,y) => -x.CompareTo(y));
        sw.Stop();
        Console.WriteLine("desc lambda took: {0} ms ", sw.ElapsedMilliseconds);

    }
    Console.Read(); 
}

But strangely, it gives the following:

ascending took: 514 ms
descending took: 537 ms
desc lambda took: 915 ms
ascending took: 511 ms
descending took: 492 ms
desc lambda took: 923 ms
ascending took: 511 ms
descending took: 483 ms
desc lambda took: 912 ms
ascending took: 511 ms
descending took: 485 ms
desc lambda took: 914 ms
ascending took: 518 ms
descending took: 485 ms
desc lambda took: 924 ms
... a.s.o. ...

So, the lambda really is slowest. But how comes, the plain ascending Array.Sort is not faster anymore? Is it, because Array.Sort(T[], Comparer) has been improved or has TrySZSort simply been removed? Or did I miss something?

(Release build, no Debug, no Reflector available right now ;) ) Thanks!

UPDATE: According to the hint by @Reed Copsey, the lambda expression is not fair. I tried to change it to the same as the comparer does. The speed went up. Asc / lambda went from 55% -> 75%. So it still is considerably slower.

like image 850
Haymo Kutschbach Avatar asked Feb 20 '12 18:02

Haymo Kutschbach


People also ask

Which sorting algorithm is used in arrays sort C#?

It uses the QuickSort algorithm.

How do you sort an Array in ascending order in C#?

Sort() and Array. Reverse() Method First, sort the array using Array. Sort() method which sorts an array ascending order then, reverse it using Array.

Is List sort stable C#?

As other answers have stated, Array. Sort isn't stable. However, the LINQ OrderBy methods (and OrderByDescending etc) are stable, which can be very useful.

How does sort work in C#?

C# is using a default comparer method to sort integers numerically. The Sort method orders the integers in ascending order, while the Reverse method in descending order. The following example sorts integers with LINQ. In LINQ, we can choose between the query syntax or the method syntax.


1 Answers

So, the lambda really is slowest. But how comes, the plain ascending Array.Sort is not faster anymore? Is it, because Array.Sort(T[], Comparer) has been improved or has TrySZSort simply been removed? Or did I miss something?

Well, there's two issues here. First, this really depends on your build and system -

On my system, in x64, Array.Sort() is the fastest, by a significant amount:

ascending took: 192 ms
descending took: 248 ms
desc lambda took: 326 ms
ascending took: 194 ms
descending took: 247 ms
desc lambda took: 326 ms

On x86, things are slightly different - but not nearly the same significance as you're showing:

ascending took: 235 ms
descending took: 223 ms
desc lambda took: 325 ms
ascending took: 234 ms
descending took: 222 ms
desc lambda took: 325 ms

Did you have the visual studio host attached when you ran these timings? Even a release build will be dramatically slower if you run within VS (ie: F5 instead of Ctrl+F5 by default).


Also note that your test isn't completely fair, in regards to the lambda. You should use the same mechanism for testing, which would be:

Array.Sort<double>(a, (x, y) => (x > y) ? -1 : 1);
like image 139
Reed Copsey Avatar answered Oct 23 '22 03:10

Reed Copsey