我在C#中实现了一个quicksort版本,并执行了一些快速基准来与C#List<T>.Sort
进行比较。我发现我的实现比库版本慢得多。我想知道为什么。这是一些粗略的基准数字。对于输入,我使用了一个随机(均匀)生成的整数列表,其中包含很少的重复元素。 请注意,所有基准时间均为多次运行的平均值。
100,000 elements
My code 0.096 seconds
List<T>.Sort 0.011 seconds
1,000,000 elements
My code 1.10 seconds
List<T>.Sort 0.14 seconds
我的代码如下。这是我尝试过的优化列表 他们的结果:
Swap
和。{
ChoosePivotIndex
函数我看到了大约10%的改进。List<T>.Sort
声明要做的那样)。这可以带来大约20%的改善。结合这些优化,我已经能够将我的代码缩小到
100,000 elements - 0.062 seconds
1,000,000 elements - 0.740 seconds
这仍然比库Sort慢得多。在我的代码中有没有明显的解释性能差距,或者是从更小的调整中剩下的70-80%的差距? 请注意,以下代码是我未经优化的基础版本
public class Quicksorter<T> where T : IComparable<T>
{
protected Random random;
public Quicksorter()
{
random = new Random();
}
public void Sort(IList<T> items)
{
Partition(items, 0, items.Count-1);
}
private void Partition(IList<T> items, int startIndex, int endIndex)
{
if (startIndex >= endIndex)
return;
int pivotIndex = ChoosePivotIndex(items, startIndex, endIndex);
T pivot = items[pivotIndex];
// swap pivot and first element
Swap(items, startIndex, pivotIndex);
int partitionIndex = startIndex + 1;
for (int frontierIndex = partitionIndex; frontierIndex <= endIndex; frontierIndex++)
{
if (items[frontierIndex].CompareTo(pivot) < 0)
{
Swap(items, frontierIndex, partitionIndex);
partitionIndex++;
}
}
// put pivot back
items[startIndex] = items[partitionIndex-1];
items[partitionIndex - 1] = pivot;
// recursively sort left half
Partition(items, startIndex, partitionIndex - 2);
// recursively sort right half
Partition(items, partitionIndex, endIndex);
}
protected virtual int ChoosePivotIndex(IList<T> items, int startIndex, int endIndex)
{
return random.Next(startIndex, endIndex);
}
private void Swap(IList<T> items, int aIndex, int bIndex)
{
T temp = items[aIndex];
items[aIndex] = items[bIndex];
items[bIndex] = temp;
}
}
答案 0 :(得分:6)
因为.NET Framework具有整数,字符串和其他内置类型的特殊情况排序方法。它们不会产生调用代表进行比较等的成本。如果你使用内置类型比较你的排序,那么库排序通常要快得多。