Bodigrim / tasty-bench

Featherlight benchmark framework, drop-in replacement for criterion and gauge.
https://hackage.haskell.org/package/tasty-bench
MIT License
80 stars 11 forks source link

Benchmarking a memoized function #37

Closed dschrempf closed 2 years ago

dschrempf commented 2 years ago

Hello,

I noticed that the benchmarking results for functions including internal memoization are surprising (or maybe they shouldn't be surprising; see https://github.com/haskell/criterion/issues/85). In particular, the first function call takes long, as expected, and all other calls use the memoized value (I didn't expect this). The final result only reflects the time it takes to retrieve the memoized value, once it has been calculated.

Is it possible to benchmark a memoized function? That is, let the memoization work "within a benchmarking function call", but not "across benchmarking function calls".

EDIT: Is this maybe also important for normal functions that use some type of data that has to be initialized (calculated) and can be reused?

Bodigrim commented 2 years ago

I don't see how this can be achieved. E. g.,

fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

fib :: Int -> Integer
fib n = fibs !! n 

main :: IO ()
main = defaultMain [ bench "fib" $ nf fib 100 ]

There is no way for bench or nf to inspect fib and learn that it memoizes its calculations in a top-level binding fibs, saying nothing of preventing such memoization.

dschrempf commented 2 years ago

Thanks for your reply! That confirms my suspicion. I guess there is no way around creating "sub-binaries" and use hyperfine or something similar.