Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 按降序排列数组的最快方法_C#_Sorting - Fatal编程技术网

C# 按降序排列数组的最快方法

C# 按降序排列数组的最快方法,c#,sorting,C#,Sorting,为什么会出现以下代码 Array.Sort(values); Array.Reverse(values); 按降序排序数组比按降序排序快得多 Array.Sort(values, (a,b)=>(-a.CompareTo(b))); 代码在调试器外部的发布模式下运行 为数组生成降序排序的最有效方法是什么,最好是在一行中?这是一个很好的问题。我打赌你的值数组是一个原始类型的数组 这里真正占主导地位的是排序,因为反向的复杂性是O(n),而排序是O(n logn) 问题是,在对基本类型进行排

为什么会出现以下代码

Array.Sort(values);
Array.Reverse(values);
按降序排序数组比按降序排序快得多

Array.Sort(values, (a,b)=>(-a.CompareTo(b)));
代码在调试器外部的发布模式下运行


为数组生成降序排序的最有效方法是什么,最好是在一行中?

这是一个很好的问题。我打赌你的值数组是一个原始类型的数组

这里真正占主导地位的是排序,因为反向的复杂性是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);
}
[可靠性合同(Consistency.MayCorruptInstance,Cer.MayFail)]
[安全性安全关键]
公共静态void排序(T[]数组、int索引、int长度、IComparer比较器)
{
if(数组==null)
抛出新的ArgumentNullException(“数组”);
否则如果(索引<0 | |长度<0)
抛出新ArgumentOutOfRangeException(长度<0?):“index”,Environment.GetResourceString(“ArgumentOutOfRange_NeedNonNegNum”);
else if(array.Length-索引<长度)
抛出新的ArgumentException(Environment.GetResourceString(“Argument_InvalidOffLen”);
如果(长度>1&&(比较器!=null&&comparer!=comparer.Default | | |!数组.TrySZSort((数组)数组,(数组)null,index,index+length-1)),则为else
ArraySortHelper.Default.Sort(数组、索引、长度、比较器);
}
作为

这里的排序方法总是以内部TrySZSort或QuickSort结束 方法,当它不引发异常时。tryssort内部 该方法针对一维阵列(也称为“零”)进行了优化 数组或向量

因为基类库中使用的TrySZSort方法是 它是用本机代码实现的,经过了大量优化。所以,, 这种方法可能比用C语言编写的任何解决方案都要快# 语言

代表们

对委托的调用比对
IComparable.CompareTo的默认调用慢得多

更新:

如果您想要相同(或接近)的速度,请实现
IComparer
接口并将其传递给sort方法


因为在第二个版本中,它必须在每次执行比较时调用(匿名)函数,然后在其中调用.CompareTo,所以您有两个间接,否则它可以使用内置比较(对于基本类型)


基本上,您需要支付函数调用开销,我敢打赌,在执行这些类型的操作时,本机基元类型可以消除这些开销。虽然技术上可能(我认为),但我怀疑抖动是否能够在第二种情况下完全内联它们。

如果用普通方法替换匿名方法,是否可以重现这种情况?您是否尝试过使用不调用旧比较器的非匿名自定义比较器?差别有多大?另外,您是否遵循了类似以下的教程来考虑微观基准测试?因为这是一件非常困难的事情。微软提供的源代码甚至可以得到注释
TrySZSort仍然比一般实现更快。原因是Int32.CompareTo仍然比仅使用“”昂贵。
对于未指定比较器的情况:DAlso提供
比较
而不是
IComparer
强制框架进行包装,因为内部实现使用比较器。。。另外一个间接层次(快速但每次比较都会执行)说法拉利比莫里斯小轿车快,但没有说明原因,这并不是真正的答案。