开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜