简体   繁体   中英

How does laziness affect benchmarking in Haskell?

This question is related to the following question : How to force evaluation in Haskell?

I want to benchmark the algorithm quicksort for a list. For this I have made a certain number of files which have random numbers in them.

Here is the relevant part of the code in question :

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)

I do not want to know want to measure the time the program takes to look into the files, just the one that the sorting takes. Because of laziness, I think that the list l is only evaluated when deepseq is called on the list l' and that gives a flawed benchmark. Am I correct ?

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

Correct.

...and that gives a flawed benchmark.

Let me make an assumption about what you mean by "flawed". I guess what you mean is that getCurrentTime will return a time from before the sort is fully completed. Under that assumption, no, the benchmark is not flawed. I'm not sure I can explain which part of your reasoning is wrong, though, because you don't say why you think the benchmark will be flawed.

However, there is a pitfall to be aware of that I suspect is different from the one you had in mind: you should make sure that the input list is fully evaluated before calling the starting getCurrentTime , thus:

  start <- l `deepseq` getCurrentTime

This may or may not matter, depending on exactly how you implemented getListFromFiles .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM