Force evaluation in order to time computation

I’m working on a problem from the challenge website Project Euler. (It provides mathy problems you can solve with coding mainly for fun.) I’m working with a problem about pentagonal numbers which are generated according to the formula

P_i = i * (3*i - 1) `div` 2

Then there’s a problem about finding certain pairs of pentagonal numbers which requires both looking up P_i quickly and checking if a particular number X is in the set of pentagonal numbers, so I figured I would write a function to generate a list of pentagonal numbers, then convert that list into a Set so I can have O(log n) lookup of membership, and an array so I can have O(1) lookup by index. After that an O(N^2) algorithm runs looking for viable pairs according to the criteria you need to solve the problem.

I’d like to get a sense how much time is spent calculating that set and array. I was thinking maybe I could use Debug.Trace and print something after forcing evaluation of the set and array, giving me a quick way of measuring what fraction of the run time is devoted to the precalculation. Is this possible and how would I do it?

1 Like

I’m not sure why you want to use Debug.Trace instead of just printing something in IO, as normal. For example:

example = do
    t0 <- getTime
    _ <- evaluate (computation arg1 arg2 ...)
    t1 <- getTime
    putStrLn ("Total time was: " <> show (t1 - t0))

But maybe there’s a reason this doesn’t work for your use case? If so could you please clarify?

You’ll also have to make sure that evaluating computation calculates everything that you care about, rather than leaving it in unevaluated thunks, but that’s a different question.

1 Like

This is a tangent, but in some ways Debug.Trace is the ideal way to print and log. It uses stderr, and it does the right thing on Windows even when a tty isn’t present (and hPutStrLn stderr will cause the program to crash).

Thanks, most of this was pure code so I didn’t think to use putStrLn, but that will probably work best.