为什么是以下代码
Array.Sort(values);
Array.Reverse(values);
与
相比,按降序排序数组要快得多Array.Sort(values, (a,b)=>(-a.CompareTo(b)));
代码在调试器之外的发布模式下运行。
为阵列生成降序排序的最有效方法是什么?最好是在一个班轮中?
答案 0 :(得分:21)
这是一个很好的问题。我敢打赌你的values数组是一个原始类型的数组!
这真的是这里的主导,因为Reverse的复杂性是O(n),而排序是O(n logn)。
问题在于,在对基本类型进行排序时,.NET实际上调用了一个非常快的本机函数 - 比使用比较或比较器快得多。
该函数名为TrySZSort
:
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
private static bool TrySZSort(Array keys, Array items, int left, int right);
以下是它在Array类中的调用方式:
[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);
}
答案 1 :(得分:4)
此处的排序方法始终以内部TrySZSort或QuickSort结束 不抛出异常的方法。 TrySZSort内部 方法针对一维数组进行了优化,也称为“零” 数组或向量
因为基类库中使用的TrySZSort方法是 在本机代码中实现,它已经过大量优化。因此, 这个方法可能比用C#编写的任何解决方案都快 语言
答案 2 :(得分:3)
委托。
对委托的调用比默认调用IComparable.CompareTo
<强>更新强>
如果您想要相同(或接近)的速度,请实现IComparer
接口并将其传递给sort方法。
答案 3 :(得分:2)
因为在你的第二个版本中,它必须在每次进行比较时调用你的(匿名)函数,然后在其中调用.CompareTo,所以你有两个间接,否则它可以使用内置比较(对于基本类型) )。
基本上你支付函数调用开销,我打赌在执行这些操作时会删除本机基元类型。虽然技术上可行(我认为),但我怀疑Jitter能够在第二种情况下完全内联它们。