how to force the evaluation of this expression?
module Main where
import Control.Parallel(par,pseq)
import Text.Printf
import Control.Exception
import System.CPUTime
import Data.List
import IO
import Data.Char
import Control.DeepSeq
time :: IO t -> IO t
time a = do
start <- getCPUTime
v <- a
end <- getCPUTime
let diff = (fromIntegral (end - start)) / (10^12)
printf "Computation time: %0.3f sec\n" (diff :: Double)
return v
learquivo :: FilePath -> IO ([[Int]])
learquivo s = do
content <- readFile s
return (read content)
main :: IO ()
main = do
t5 <- getCPUTime
content <- learquivo "mkList1.txt"
let !mapasort = rnf $ map sort content
t6 <- getCPUTime
let diffft6t5 = (fromIntegral (t6 - t5)) / (10^12)
printf "Computation time Mapasort: %0.3f sec\n" (diffft6t5 :: Double)
How to tell if it evaluates all elements of content?
let !mapasort = rnf $ map sort content
I used the line in winghci:
*Main> let !mapasort = rnf $ map sort content
But, returned:
开发者_Go百科*Main> mapasort ()
Thanks
I see two questions:
1) Why is mapsort evaluating to unit, ()
.
Because the rnf
function always returns ()
. See the documentation.
2) Is everything evaluated
Yes. The DeepSeq instance (which is where rnf
lives) for list just calls the deepseq instance for each element in the list:
rnf [] = ()
rnf (x:xs) = rnf x `seq` rnf xs
Your elements all Ints, which have a correct NFData instance.
And I'd add two more questions:
3) How should this benchmarking be done correctly?
Using Criterion. There are many Criterion advocates here on SO, you can find answers that would serve as good examples with a search.
4) How should this evaluation be forced for non-benchmarking purposes?
Using the parallel package.
import Control.Parallel.Strategies
...
let !mapsort = (map sort content) `using` (evalList rdeepseq)
or still using rnf
:
let mapsort = map sort content
!_ = rnf mapsort
精彩评论