测试了一下LINQ写的Quick Sort性能

        昨晚看到一个帖子, 说的是三行代码实现快速排序, 文中实现Quick Sort代码如下:

public static IEnumerable<T> QuickSort<T>(IEnumerable<T> list) where T : IComparable<T>
{
    if (list.Count() <= 1) return list;

    var pivot = list.First();

    return QuickSort(list.Where(x => x.CompareTo(pivot) < 0))
                    .Concat(list.Where(x => x.CompareTo(pivot) == 0))
                    .Concat(QuickSort(list.Where(x => x.CompareTo(pivot) > 0)));
}

        不由想起老赵两年前(正好整整两年天使)的一个帖子: 趣味编程:函数式链表的快速排序. 虽说在LINQ技术下, 三行代码是可以将快速排序的思路很直白明了的呈现出来, 这是函数式编程的优点. 看到这段代码里三个Where, 我心里不免有些疑问, Where不就枚举了整个链表了么, 这样做还是所谓的"Quick Sort"吗. 因此我用老赵的CodeTimer测试了一下它的性能, 并与传统的快速排序做个比较.

        传统的的Quick Sort算法摘自维基百科:

public static void Sort(int[] numbers)
{
    Sort(numbers, 0, numbers.Length - 1);
}

private static void Sort(int[] numbers, int left, int right)
{
    if (left < right)
    {
        int middle = numbers[(left + right) / 2];
        int i = left - 1;
        int j = right + 1;
        while (true)
        {
            while (numbers[++i] < middle) ;

            while (numbers[--j] > middle) ;

            if (i >= j)
                break;

            Swap(numbers, i, j);
        }

        Sort(numbers, left, i - 1);
        Sort(numbers, j + 1, right);
    }
}

private static void Swap(int[] numbers, int i, int j)
{
    int number = numbers[i];
    numbers[i] = numbers[j];
    numbers[j] = number;
}

        由于CodeTimer最后一个参数是一个Action委托, 我对两种快速排序算法包装了一下, 然后测试的时候就执行这两个方法:

public static void FunctionalQuickSort()
{
    int[] array = new int[] { 49, 38, 65, 97, 76, 13, 27 };
    QuickSort(array);
}

public static void NormalQuickSort()
{
    int[] array = new int[] { 49, 38, 65, 97, 76, 13, 27 };
    Sort(array);
}

        调用CodeTimer的Time方法, 就可以得到性能数据:

//参数分别为: 输出的方法名字, 方法执行次数, 方法体
CodeTimer.Time("Functional Quick Sort", 10000, () => FunctionalQuickSort());
CodeTimer.Time("Normal Quick Sort", 10000, () => NormalQuickSort());

        做了几次测试, 得到的测试数据基本上是这个情况:

2011082717044436.png

        这还只是7个数据的排序, 如果数据越多, 用LINQ写出来的算法性能劣势就越明显.

        另外我发现百度里讲解快速排序的算法过程真是坑爹, 我看了一下它那个过程, 觉得好像有点不对头, 自己在纸上又画了一遍, 真不明白它这句"此时再执行第三步的时候就发现 i=j, 从而结束一趟快速排序"是怎么来的...第一趟排序什么时候 i=j 过的...

步骤序列ij
049 38 65 97 76 13 2706
149 38 65 97 76 13 2706
227 38 65 97 76 13 4926
327 38 49 97 76 13 6525
427 38 13 97 76 49 6535
527 38 13 49 76 97 6532

        由此看来, 一方面是简洁的书写代码, 另一方面是性能的考量, 您会选择哪种呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值