text-0.11.2.3: benchmarks/haskell/Timer.hs
{-# LANGUAGE BangPatterns #-}
module Timer (timer) where
import Control.Exception (evaluate)
import Data.Time.Clock.POSIX (getPOSIXTime)
import GHC.Float (FFFormat(..), formatRealFloat)
ickyRound :: Int -> Double -> String
ickyRound k = formatRealFloat FFFixed (Just k)
timer :: Int -> a -> (a -> b) -> IO String
timer count a0 f = do
let loop !k !fastest
| k <= 0 = return fastest
| otherwise = do
start <- getPOSIXTime
let inner a i
| i <= 0 = return ()
| otherwise = evaluate (f a) >> inner a (i-1)
inner a0 count
end <- getPOSIXTime
let elapsed = end - start
loop (k-1) (min fastest (elapsed / fromIntegral count))
t <- loop (3::Int) 1e300
let log10 x = log x / log 10
ft = realToFrac t
prec = round (log10 (fromIntegral count) - log10 ft)
return $! ickyRound prec ft
{-# NOINLINE timer #-}