首页 > 解决方案 > C# 列表.Sort - 为什么默认实现有这么好的性能?

问题描述

的两次重载之间的时间差List<T>.Sort(...)

        List<int> list = new List<int>();
        Random rand = new Random();

        for (int i = 0; i < 20_000_000; i++)
        {
            list.Add(rand.Next());
        }

        Stopwatch watch = new Stopwatch();
        watch.Start();

        //list.Sort(); // 1.77 sec
        list.Sort((n1, n2) => n1.CompareTo(n2)); // 5.80 sec

        watch.Stop();
        Console.WriteLine(watch.Elapsed.TotalSeconds);

为什么第二种形式这么慢?

标签: c#sorting

解决方案


list.Sort()最终将调用,它对传入Array.Sort比较器时进行了特定优化。

这篇博文对此进行了讨论:

.NET 中排序的核心是一个名为 TrySZSort 的外部本机函数。在幕后 Array.Sort 调用作为 CLR 本身一部分的 C++ 代码。这段代码经过了高度优化。

当您使用该list.Sort((n1, n2) => n1.CompareTo(n2))表单时,您将失去这个经过高度优化的实现:

还值得注意的是,仅对默认比较器调用 TrySZSort。如果您提供自定义比较器,它将不会被使用。对于自定义比较器,与 TrySZSort 中的排序算法类似的排序算法在托管代码中执行。当然,这缺乏非托管代码的所有好处,并且错过了大多数本机优化。


推荐阅读