1

I am relatively new to Haskell and I am trying to learn how different actions can be executed in sequence using the do notation. In particular, I am writing a program to benchmark an algorithm (a function)

foo :: [String] -> [String]

To this purpose I would like to write a function like

import System.CPUTime

benchmark :: [String] -> IO Integer
benchmark inputList = do
                         start <- getCPUTime
                         let r = foo inputList
                         end <- getCPUTime
                         return (end - start) -- Possible conversion needed.

The last line might need a conversion (e.g. to milliseconds) but this is not the topic of this question.

Is this the correct way to measure the time needed to compute function foo on some argument inputList?

In other words, will the expression foo inputList be completely reduced before the action end <- getCPUTime is executed? Or will r only be bound to the thunk foo inputList?

More in general, how can I ensure that an expression is completely evaluated before some action is executed?

2
  • Can someone explain why this question is off-topic? I may be wrong but it seems perfectly OK to me.
    – Giorgio
    Jan 27, 2014 at 11:16
  • Maybe this should be asked on stackoverflow.
    – Ray
    Aug 12, 2014 at 21:22

1 Answer 1

5

Indeed you version will not benchmark your algorithm. As r is not used it will not be evaluated at all.

You should be able to do it with DeepSeq[1]:

benchmark :: [String] -> IO Integer
benchmark inputList = do
                     start <- getCPUTime
                     let r = foo inputList
                     end <- r `deepseq` getCPUTime
                     return (end - start)

(a deepseq b) is some "magic" expression which forces the complete/recursive evaluation of 'a' before retuning 'b'.

[1] http://www.haskell.org/ghc/docs/7.4.1/html/libraries/deepseq-1.3.0.0/Control-DeepSeq.html

2
  • 1
    +1: Thanks for the answer, I will try it out today. In your code, I think you need to keep the expression let r = foo inputList between the two getCPUTime, otherwise r will be undefined.
    – Giorgio
    Aug 13, 2012 at 7:17
  • @ysdx This question is off-topic for us here on Programmers. It has been reposted on Stack Overflow where it's on-topic. If you want to repost an answer there, feel free to do so and then flag the repost of your answer for deletion to set things right. Ping me in chat for any questions.
    – Thomas Owens
    Jan 4, 2013 at 18:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.