懒惰如何影响 Haskell 中的基准测试?

How does laziness affect benchmarking in Haskell?

此问题与以下问题相关: How to force evaluation in Haskell?

我想对列表的算法快速排序进行基准测试。为此,我制作了一定数量的文件,其中包含随机数。

这是相关代码的相关部分:

import System.IO
import Data.Time
import Control.DeepSeq

getListFromFiles :: IO [[Int]]
quicksort :: (Ord a) => [a] -> [a]

main = do
  l <- getListFromFiles
  start <- getCurrentTime
  let l' = map quicksort l
  end <- l' `deepseq` getCurrentTime
  print (diffUTCTime end start)

我不想知道要测量程序查看文件所花费的时间,只是排序所花费的时间。 由于懒惰,我认为列表 l 仅在列表 l' 上调用 deepseq 时才被评估,这给出了一个有缺陷的基准。我说得对吗?

I think that the list l is only evaluated when deepseq is called on the list l'...

正确。

...and that gives a flawed benchmark.

让我假设一下 "flawed" 是什么意思。我猜你的意思是 getCurrentTime 将 return 从排序完全完成之前开始。在这个假设下,不,基准没有缺陷。不过,我不确定我能否解释您推理的哪一部分是错误的,因为您没有说明为什么您认为基准测试会有缺陷。

但是,有一个陷阱需要注意,我怀疑它与您所想的不同:您应该确保 input 列表在之前被完全评估调用起始 getCurrentTime,因此:

  start <- l `deepseq` getCurrentTime

这可能重要也可能不重要,具体取决于您的实施方式 getListFromFiles