{-# LANGUAGE PatternGuards #-}-- | Running benchmarks and collecting timings. ---- These functions expect the given `Build` commands to succeed,-- throwing an error if they don't. If you're not sure whether your command will succeed then test it first.moduleBuildBox.Benchmark(moduleBuildBox.Benchmark.TimeAspect,moduleBuildBox.Benchmark.Pretty,moduleBuildBox.Benchmark.Compare-- * Types,Benchmark(..),Timing(..),BenchRunResult(..),BenchResult(..)-- * Benchmarking,runTimedCommand,runBenchmarkOnce,outRunBenchmarkOnce,outRunBenchmarkAgainst,outRunBenchmarkWith)whereimportBuildBox.BuildimportBuildBox.PrettyimportBuildBox.Benchmark.BaseimportBuildBox.Benchmark.TimeAspectimportBuildBox.Benchmark.PrettyimportBuildBox.Benchmark.CompareimportData.TimeimportData.ListimportControl.Monad-- Running Commands --------------------------------------------------------------------------------- | Run a command, returning its elapsed time.runTimedCommand::Builda->Build(NominalDiffTime,a)runTimedCommandcmd=dostart<-io$getCurrentTimeresult<-cmdfinish<-io$getCurrentTimereturn(diffUTCTimefinishstart,result)-- | Run a benchmark once.runBenchmarkOnce::Benchmark->BuildBenchRunResultrunBenchmarkOncebench=do-- Run the setup commandbenchmarkSetupbench(diffTime,mKernelTimings)<-runTimedCommand$benchmarkCommandbenchbenchmarkCheckbenchreturn$BenchRunResult{benchRunResultElapsed=fromRational$toRationaldiffTime,benchRunResultKernel=mKernelTimings}-- | Run a benchmark once, logging activity and timings to the console.outRunBenchmarkOnce::Benchmark->BuildBenchRunResultoutRunBenchmarkOncebench=doout$"Running "++benchmarkNamebench++"..."result<-runBenchmarkOncebenchoutLn"ok"outLn$text" elapsed = "<>(pprFloatTime$benchRunResultElapsedresult)maybe(return())(\t->outLn$text" kernel elapsed = "<>pprFloatTimet)$takeTimeAspectOfBenchRunResultTimeAspectKernelElapsedresultmaybe(return())(\t->outLn$text" kernel cpu = "<>pprFloatTimet)$takeTimeAspectOfBenchRunResultTimeAspectKernelCpuresultmaybe(return())(\t->outLn$text" kernel system = "<>pprFloatTimet)$takeTimeAspectOfBenchRunResultTimeAspectKernelSysresultoutBlankreturnresult-- | Run a benchmark several times, logging activity to the console.-- Optionally print a comparison with a prior results.outRunBenchmarkAgainst::Int-- ^ Number of iterations.->MaybeBenchResult-- ^ Optional previous result for comparison.->Benchmark-- ^ Benchmark to run.->BuildBenchResultoutRunBenchmarkAgainstiterationsmPriorbench=doout$"Running "++benchmarkNamebench++" "++showiterations++" times..."runResults<-replicateMiterations(runBenchmarkOncebench)outLn"ok"letresult=BenchResult{benchResultName=benchmarkNamebench,benchResultRuns=runResults}outLnpprBenchResultAspectHeadermaybe(return())outLn$pprBenchResultAspectTimeAspectElapsedmPriorresultmaybe(return())outLn$pprBenchResultAspectTimeAspectKernelElapsedmPriorresultmaybe(return())outLn$pprBenchResultAspectTimeAspectKernelCpumPriorresultmaybe(return())outLn$pprBenchResultAspectTimeAspectKernelSysmPriorresultoutBlankreturnresult-- | Run a benchmark serveral times, logging activity to the console.-- Also lookup prior results for comparison from the given list.-- If there is no matching entry then run the benchmark anyway, but don't print the comparison.outRunBenchmarkWith::Int-- ^ Number of times to run each benchmark to get averages.->[BenchResult]-- ^ List of prior results.->Benchmark-- ^ The benchmark to run.->BuildBenchResultoutRunBenchmarkWithiterationspriorsbench=letmPrior=find(\b->benchResultNameb==benchmarkNamebench)priorsinoutRunBenchmarkAgainstiterationsmPriorbench