module BuildBox.Build.Benchmark
( Benchmark (..)
, BenchResult (..)
, runBenchmark
, iterateBenchmark
, timeBuild)
where
import BuildBox.Build.Base
import BuildBox.Data.Physical
import Data.Time
data Benchmark result
= forall a. Benchmark
{
benchmarkName :: String
, benchmarkSetup :: Build ()
, benchmarkCommand :: Build a
, benchmarkCheck :: a -> Build result }
data BenchResult result
= BenchResult
{ benchResultName :: String
, benchResultIteration :: Int
, benchResultTime :: Seconds
, benchResultValue :: result }
runBenchmark :: Benchmark result -> Int -> Build (BenchResult result)
runBenchmark (Benchmark name setup cmd check) i
= do setup
(secs, x) <- timeBuild cmd
r <- check x
return $ BenchResult name i secs r
iterateBenchmark :: Int -> Benchmark result -> Build [BenchResult result]
iterateBenchmark 0 _ = return []
iterateBenchmark count bench
= do result <- runBenchmark bench count
rest <- iterateBenchmark (count - 1) bench
return $ result : rest
timeBuild :: Build a -> Build (Seconds, a)
timeBuild cmd
= do start <- io $ getCurrentTime
result <- cmd
finish <- io $ getCurrentTime
let time = fromRational $ toRational $ diffUTCTime finish start
return (Seconds time, result)