Haskell: cannot use getCPUTime

I have:

main :: IO () main = do iniciofibonaccimap <- getCPUTime let fibonaccimap = map fib listaVintesete fimfibonaccimap <- getCPUTime let difffibonaccimap = (fromIntegral (fimfibonaccimap - iniciofibonaccimap)) / (10^12) printf "Computation time fibonaccimap: %0.3f sec\n" (difffibonaccimap :: Double) listaVintesete :: [Integer] listaVintesete = replicate 100 27 fib :: Integer -> Integer fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) 

But

 *Main> main Computation time fibonaccimap: 0.000 sec 

I do not understand why this is happening. Help me, thanks.

+4
source share
5 answers

Haskell is lazy. The calculation requested in the string

 let fibonaccimap = map fib listaVintesete 

doesn't really happen until you somehow use the fibonaccimap value. Thus, in order to measure the time used, you need to enter something that will cause the program to perform the actual calculation.

ETA: Initially, I suggested printing the last element for a forced evaluation. As TomMD points out, this is nowhere near good enough - I highly recommend reading his answer here to really work on this particular piece of code.

+7
source

As others have said, this is due to lazy appreciation. For a forced evaluation, you should use deepseq and BangPatterns :

 {-# LANGUAGE BangPatterns #-} import Control.DeepSeq import Text.Printf import System.CPUTime main :: IO () main = do iniciofibonaccimap <- getCPUTime let !fibonaccimap = rnf $ map fib listaVintesete fimfibonaccimap <- getCPUTime let difffibonaccimap = (fromIntegral (fimfibonaccimap - iniciofibonaccimap)) / (10^12) printf "Computation time fibonaccimap: %0.3f sec\n" (difffibonaccimap :: Double) ... 

In the above code you should notice three things:

  • It compiles (modulo ... functions you defined above). When you submit a code for questions, please make sure that it works (for example, you must include import).
  • Using rnf from deepseq . This forces you to evaluate each item in the list.
  • Figure bang on !fibonaccimap , which means "do it now, don't wait." This leads to the fact that the list will be evaluated in the form of a weak head (basically, only the first constructor (:) ). Without this, the rnf function alone will be invaluable.

Result:

 $ ghc --make ds.hs $ ./ds Computation time fibonaccimap: 6.603 sec 

If you intend to benchmark, you should also use optimization ( -O2 ) and Criterion instead of getCPUTime .

+7
source

I suspect that you are a β€œvictim” lazy assessment . Nothing forces Fibonacci to be evaluated between synchronization calls, so it is not calculated.

Edit I suspect that you are trying to compare your code, in which case you should indicate that the best ways to do this are more reliable.

+4
source

10^12 is an integer that makes the value fromIntegral be an integer, which means that the difffibonaccimap assigned a rounded value, so it is 0 if the time is less than half a second. Anyway, I guess I don’t have time for this.)

0
source

A lazy assessment actually bit you, as the other answers said. In particular, "let" does not force evaluation of the expression; it simply displays the variable. The calculation will not actually happen until its value requires something, which probably will not happen until the actual operation of the AI ​​does not need its value. So you need to put your print statement between getCPUTime evaluations. Of course, this will also give the processor time used by printing there, but most of the printing time awaits I / O. (Terminals are slow.)

0
source

All Articles