List
模块包含sortDescending
函数,用于将列表从高到低排序。我读到它只是对列表进行排序然后反转它更快。所以我尝试了,情况似乎就是这样。
[1.0..1000000.0] |> List.sortDescending;;
Real: 00:00:00.322, CPU: 00:00:00.328, GC gen0: 10, gen1: 4, gen2: 0
[1.0..1000000.0] |> List.sort |> List.rev;;
Real: 00:00:00.243, CPU: 00:00:00.250, GC gen0: 15, gen1: 7, gen2: 0
(我尝试了很多次,这些值很典型)
是否有理由使用sortDescending
而不是仅排序列表然后反转结果?
答案 0 :(得分:4)
目前,对于没有身份的事物(如整数和浮点数),排序和反转应该更快。如果查看video上的源代码(请参阅list.fs和local.fs),则将列表复制到数组中,对数组进行排序,然后重新创建列表。
当您使用sortDescending
时,它会使用stableSortInPlaceWith
对数组进行排序,stableSortWithKeysAndComparer
始终使用stableSortInPlace
。排序后,此函数会生成结果的副本并调整重复的项目,使它们按原始顺序排列。这是一个github所以重复的项目不会移动。
排序使用List.sort
,它具有优化功能,可以检测没有身份的浮动内容,因此不需要使用稳定排序;没有第二个副本使其更快。如果它是一个对象列表,stableSortWithKeysAndComparer
则使用 [1.0..1000000.0] |> List.map Some |> List.sortDescending;;
Real: 00:00:13.616, CPU: 00:00:13.275, GC gen0: 146, gen1: 12, gen2: 5
[1.0..1000000.0] |> List.map Some |> List.sort |> List.rev;;
Real: 00:00:17.727, CPU: 00:00:17.316, GC gen0: 149, gen1: 15, gen2: 6
,因此它应该与List.sortDescending的速度相同,但由于反向速度较慢。对于我的测试来说,由于我的虚拟机在共享基础架构上并且给出了截然不同的结果,因此速度较慢但难以确定。
List.sort
正如评论中指出的那样,列表已经排序,使得List.sort |> List.rev
快得多(最后我看过,.NET使用快速排序的数组,如果已经排序则速度很快)。但是,即使您首先撤消列表,List.sortDescending
仍然比List.sortDescending
更快,因为它是双打列表。
还有一点需要注意,这两个实际上并不等同于所有情况。由于它是一个稳定的排序,重复的项目将在List.sort |> List.rev
之后按相同的顺序排列,但它们会被{{1}}反转。