c# - 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);
为什么第二种形式这么慢?
解决方案
list.Sort()
最终将调用,它对未传入Array.Sort
比较器时进行了特定优化。
这篇博文对此进行了讨论:
.NET 中排序的核心是一个名为 TrySZSort 的外部本机函数。在幕后 Array.Sort 调用作为 CLR 本身一部分的 C++ 代码。这段代码经过了高度优化。
当您使用该list.Sort((n1, n2) => n1.CompareTo(n2))
表单时,您将失去这个经过高度优化的实现:
还值得注意的是,仅对默认比较器调用 TrySZSort。如果您提供自定义比较器,它将不会被使用。对于自定义比较器,与 TrySZSort 中的排序算法类似的排序算法在托管代码中执行。当然,这缺乏非托管代码的所有好处,并且错过了大多数本机优化。
推荐阅读
- java - 围绕夏令时转换解析 ZonedDateTime 失败
- android-studio - Android Studio 的设计视图和 gradle 不起作用
- python - 使用 dt = CachedAccessor("dt", CombinedDatetimelikeProperties) 时,异常字符串索引必须是整数
- python - 如何使用 plotly 中的旭日图来显示每个分支的平均值而不是总和/总数?
- javascript - 将值传递给其他参数后,值变得未定义
- php - Laravel Pusher/Echo 在 Laravel 中捕获 ping 超时或 websocket 断开连接
- html - 如何使我的网页上的元素位于其容器的相对两侧,而不是彼此相邻?
- git - 如何获取我贡献的开源项目的最新代码
- mysql - sql like 整数运算符
- c# - “天气预报”是什么意思?