buildbox-2.2.1.2: BuildBox/Build/Benchmark.hs
module BuildBox.Build.Benchmark
( Benchmark (..)
, BenchResult (..)
, runBenchmark
, iterateBenchmark
, timeBuild)
where
import BuildBox.Build.Base
import BuildBox.Data.Physical
import Data.Time
-- | Benchmark definition.
data Benchmark result
= forall a. Benchmark
{ -- | A unique name for the benchmark
benchmarkName :: String
-- | Setup command to run before the main benchmark.
-- This does not contribute to the reported time of the overall result.
, benchmarkSetup :: Build ()
-- | The main command to benchmark.
, benchmarkCommand :: Build a
-- | Check and post-process the result of the main command.
-- This does not contribute to the reported time of the overall result.
, benchmarkCheck :: a -> Build result }
-- | Benchmark result.
data BenchResult result
= BenchResult
{ benchResultName :: String
, benchResultIteration :: Int
, benchResultTime :: Seconds
, benchResultValue :: result }
-- | Run a benchmark a single time.
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
-- | Run a benchmark the given number of times.
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
-- | Run a command, returning its elapsed time.
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)