Why is the following code
Array.Sort(values);
Array.Reverse(values);
much faster at sorting an array in descending order compared to
<As the link points out
Sort method here always ends up in an internal TrySZSort or QuickSort method when it doesn't throw an exception. The TrySZSort internal method is optimized for one-dimensional arrays, also known as "Zero" arrays or vectors
Because the TrySZSort method used in the base class libraries is implemented in native code, it has been heavily optimized. Therefore, this method is likely faster than any solution written in the C# language
Delegates.
The call to the delegate is much slower than the default call to IComparable.CompareTo
Update:
If you want the same (or close) speed, implement the IComparer
interface and pass that to the sort method.
http://msdn.microsoft.com/en-us/library/bzw8611x
That's a great question. I bet your values array is an array of primitive type!
It's really the sort that is dominant here, because the complexity of Reverse is O(n), while the sort is O(n logn).
The thing is that when sorting primitive types, .NET actually calls a native function, which is extremely fast - much faster that using a Comparison or Comparator.
The function is called TrySZSort
:
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
private static bool TrySZSort(Array keys, Array items, int left, int right);
and here is how it's called in the Array class:
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[SecuritySafeCritical]
public static void Sort<T>(T[] array, int index, int length, IComparer<T> comparer)
{
if (array == null)
throw new ArgumentNullException("array");
else if (index < 0 || length < 0)
throw new ArgumentOutOfRangeException(length < 0 ? "length" : "index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
else if (array.Length - index < length)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
else if (length > 1 && (comparer != null && comparer != Comparer<T>.Default || !Array.TrySZSort((Array) array, (Array) null, index, index + length - 1)))
ArraySortHelper<T>.Default.Sort(array, index, length, comparer);
}
Because in your second version it has to invoke your (anonymous) function each time it does a compare and then call .CompareTo inside that, so you have two indirections, whereas otherwise it can use build-in comparisons (for primitive types).
Basically you pay for function call overhead which I bet are eliminated for native primitive types when doing these sorts of operations. Though technically possible (I think), I doubt the Jitter is able to completely inline them in your second case.