Haskell中函数合成的运行时

Haskell中函数合成的运行时,haskell,Haskell,做 或 尝试按降序对整数列表排序时运行得更快?我使用(reverse.sort)和(sortBy(向下比较))启动了一个标准测试排序。要排序的列表是按顺序和反向顺序排列的(应该是最坏和最好的情况,不一定按顺序排列) 代码 总结结果 撤销清单是昂贵的。使用反向的最佳案例测试仍然显著(统计上)慢于使用排序的最坏案例 平均运行时间为: 排序,最坏情况:552us 排序,最佳情况:308us 糟糕的是,最坏的情况是:263us 排序,最佳情况:168us 做 相反。排序 或 sortBy 尝试按降序


尝试按降序对整数列表排序时运行得更快?

我使用
(reverse.sort)
(sortBy(向下比较))
启动了一个标准测试排序。要排序的列表是按顺序和反向顺序排列的(应该是最坏和最好的情况,不一定按顺序排列)

代码 总结结果 撤销清单是昂贵的。使用
反向
的最佳案例测试仍然显著(统计上)慢于使用
排序的最坏案例

平均运行时间为:

  • 排序,最坏情况:552us
  • 排序,最佳情况:308us
  • 糟糕的是,最坏的情况是:263us
  • 排序,最佳情况:168us

相反。排序

sortBy

尝试按降序对整数列表排序时运行得更快


sortBy
会更快。在
reverse中
遍历整个列表,因此
reverse。排序
将遍历整个列表两次。事实上,另一个答案的基准非常接近
reverse的两倍。排序
!如果使用
sortBy
只需翻转比较测试,因此在所有情况下都是首选。

性能肯定取决于输入的顺序,但我不确定在使用这些函数时如何操作。为什么不试试看呢?使用标准或在命令行中简单地使用
+RTS-s-RTS
为每个标准编写一个简单的案例。我想
sortBy
更快,因为
sort
是根据
sortBy
定义的,并且通过使用不同的比较函数可以避免通过
reverse
进行额外的遍历。但是我不知道这个比较如何衡量函数组合的成本。我不相信你的结果是准确的。您只对WHNF求值,这意味着大多数输出可能永远不会排序。可能是排序结果。排序应该是准确的。对NF进行评估的结果为347/598us进行排序,224/316us。排序结果与WHNF相差约40 US,排序结果与WHNF相差约54 US。在统计上,最好的反向和最坏的反向之间的差异仍然显著。此外,就复杂性而言,使用
reverse。sort
添加额外的O(n)操作进行排序,而sortBy(最坏情况下)添加常量因子。事实证明,sort和sortBy的比较算法只是同一算法的反向版本(因此具有相似的性能),并且都使用相同的排序算法,因此O(n)步是基准中的决定因素。是的,虽然评估策略确实影响总体时间,它似乎没有改变相对性能。我确实看到了一个奇怪的差异,在两个系统上(使用
nf
whnf
),sortBy的最坏情况始终比sort的最佳情况稍慢。并不是说它使
相反。排序
更好的选择。@JohnL不足为奇。NF不应该是必要的。WHNF是spine严格的,因为您正在评估排序列表的spine(不是任何中间步骤),并且所有元素都是为了比较而评估的,所以NF只是对列表进行额外的O(n)遍历,强制每个元素(不必要地)。至于你的结果,你是用
-O2
编译的吗?
reverse . sort
sortBy
import Criterion
import Criterion.Main

import Data.List
import Data.Ord

main :: IO ()
main = defaultMain [ bench "Sort, forward" (whnf (reverse . sort) ([1..10000] :: [Int]))
                   , bench "Sort, backward" (whnf (reverse . sort) ([10000,9999..1] :: [Int]))
                   , bench "sortby, forward" (whnf (sortBy (comparing Down)) ([1..10000] :: [Int]))
                   , bench "sortby, backward" (whnf (sortBy (comparing Down))  ([10000,9999..1] :: [Int]))
                   ]

{-
warming up
estimating clock resolution...
mean is 2.290904 us (320001 iterations)
found 79468 outliers among 319999 samples (24.8%)
  734 (0.2%) low severe
  78734 (24.6%) high severe
estimating cost of a clock call...
mean is 512.8809 ns (23 iterations)
found 4 outliers among 23 samples (17.4%)
  2 (8.7%) high mild
  2 (8.7%) high severe

benchmarking Sort, forward
mean: 551.4973 us, lb 549.7330 us, ub 553.6538 us, ci 0.950
std dev: 9.998922 us, lb 8.400519 us, ub 12.37726 us, ci 0.950
found 4 outliers among 100 samples (4.0%)
  4 (4.0%) high mild
variance introduced by outliers: 11.316%
variance is moderately inflated by outliers

benchmarking Sort, backward
mean: 307.6627 us, lb 306.6471 us, ub 308.9350 us, ci 0.950
std dev: 5.790552 us, lb 4.777178 us, ub 7.103792 us, ci 0.950
found 9 outliers among 100 samples (9.0%)
  7 (7.0%) high mild
  2 (2.0%) high severe
variance introduced by outliers: 11.365%
variance is moderately inflated by outliers

benchmarking sortby, forward
mean: 168.2486 us, lb 167.7343 us, ub 168.8683 us, ci 0.950
std dev: 2.880548 us, lb 2.448853 us, ub 3.394461 us, ci 0.950
found 4 outliers among 100 samples (4.0%)
  4 (4.0%) high mild
variance introduced by outliers: 9.467%
variance is slightly inflated by outliers

benchmarking sortby, backward
mean: 262.6001 us, lb 261.3540 us, ub 264.1395 us, ci 0.950
std dev: 7.096662 us, lb 6.053786 us, ub 8.634885 us, ci 0.950
found 3 outliers among 100 samples (3.0%)
  3 (3.0%) high mild
variance introduced by outliers: 20.965%
variance is moderately inflated by outliers
-}