
Apologies for a newbie question, but I am seeking advice on how to benchmark a pure function that returns an unlifted type. I've heard tell that `criterion` is good for benchmarking, and so I'm using that library (but have no particular allegiance to it, if something else is better). Specifically, I'm comparing a function over unlifted types with the same function written over lifted types, trying to observe how much we pay for the boxing/unboxing. To benchmark the lifted version, I just use criterion's whnf function. That seems to be working splendidly. Of course, whnf doesn't work over unlifted types, so I found its source code and inlined it. This compiles. But it doesn't work! No matter what I do, the unlifted version measures in the nanoseconds. I'm guessing that GHC "cleverly" is avoiding recomputation. How can I stop this? Here is my code:
main :: IO () main = do initializeTime let lifted = whnf fastSumPrimes 100000
unlifted = Benchmarkable go where go n | n <= 0 = return () | otherwise = let x = fastSumPrimes# 100000# in go (n-1)
benchmark lifted benchmark unlifted
I've tried increasing the argument in the unlifted case, to no avail. I've also tried using `case` instead of `let`. -ddump-simpl suggests that fastSumPrimes# is really being called, but I'm dubious. Can anyone offer advice? Thanks! Richard