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:
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.
It uses the QuickSort algorithm.
Sort() and Array. Reverse() Method First, sort the array using Array. Sort() method which sorts an array ascending order then, reverse it using Array.
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.
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.
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);
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