AERN-Basics-2011.1: src/Numeric/AERN/Basics/Bench.hs
{-|
Module : Numeric.AERN.Basics.Bench
Description : miscellaneous utilities for benchmarking
Copyright : (c) Michal Konecny
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : portable
Miscellaneous utilities for benchmarking using Criterion.
-}
module Numeric.AERN.Basics.Bench where
import qualified Numeric.AERN.Basics.RefinementOrder as RefOrd
import Numeric.AERN.Basics.Effort
import Control.DeepSeq
import Criterion
import Criterion.Config
import qualified Criterion.MultiMap as M
import Test.QuickCheck
import Test.QuickCheck.Gen
import System.Random
--runBenchmarksQ ::
-- [(Benchmark, q)] -> [(Double,q)]
--runBenchmarksQ
criterionConfig name samples =
defaultConfig
{
cfgSummaryFile = ljust $ name ++ ".csv",
cfgSamples = ljust samples,
cfgResamples = ljust 200,
cfgPlotSameAxis = ljust True,
cfgPerformGC = ljust True
-- ,
-- cfgPlot = M.singleton KernelDensity (PDF 1024 780)
}
mkBenchAreasSequences1 ::
(RefOrd.ArbitraryOrderedTuple t, EffortIndicator ei, NFData t) =>
(ei -> t -> String) {-^ function constructing benchmark names -} ->
(ei -> t -> t) {-^ function to benchmark -} ->
[(String, RefOrd.Area t)] {-^ areas in the input space and their descriptions; empty means whole space only -} ->
Int {-^ how many benchmarks to generate -} ->
ei -> t -> [Benchmark]
mkBenchAreasSequences1 mkComment fnEff [] n initEffort sample =
mkBenchSequence1 mkComment fnEff Nothing n initEffort sample
mkBenchAreasSequences1 mkComment fnEff areas n initEffort sample =
map areaSequence areas
where
areaSequence (descr, area) =
bgroup descr $ mkBenchSequence1 mkComment fnEff (Just area) n initEffort sample
mkBenchSequence1 ::
(RefOrd.ArbitraryOrderedTuple t, EffortIndicator ei, NFData t) =>
(ei -> t -> String) {-^ function constructing benchmark names -} ->
(ei -> t -> t) {-^ function to benchmark -} ->
(Maybe (RefOrd.Area t)) {-^ area in the input space; Nothing means whole space only -} ->
Int {-^ how many benchmarks to generate -} ->
ei -> t -> [Benchmark]
mkBenchSequence1 mkComment fnEff maybeArea n initEffort sample =
map mkBench $ zip3 [1..n] efforts inputs
where
mkBench (n, effort, [input]) =
bench name (nf (\(e,i) -> fnEff e i) (effort, input))
where
name =
-- "" ++ showPad 2 n ++ ":" ++
mkComment effort input ++ ""
showPad l n =
replicate (max 0 (l - (length sn))) '0' ++ sn
where sn = show n
_ = [sample] : inputs
inputs =
map (\(g, size) -> unGen arbitraryInArea g size) $ zip gs sizes
-- get a sample sequence (always the same!)
gs =
iterate (snd . next) $ mkStdGen 111111321
-- sequence of random generators
arbitraryInArea =
case case maybeArea of
Nothing -> RefOrd.arbitraryTupleRelatedBy [1] [] []
(Just area) -> RefOrd.arbitraryTupleInAreaRelatedBy area [1] [] []
of Just gen -> gen
sizes =
concat $ map (replicate 1) $ scanl1 (*) [2,2..]
-- ie [2,4,8,16..]
-- -- ie [2,2,2,4,4,4,8,8,8..]
efforts =
concat $ map (replicate 1) $ effortIncrementSequence initEffort
mkBenchSequence2 mkComment fnEff initEffort sample1 sample2 =
map mkBench $ zip3 [1..20] efforts inputs
where
mkBench (n, effort, (input1, input2)) =
bench name (nf (\(e,i1,i2) -> fnEff e i1 i2) (effort, input1, input2))
where
name =
"(" ++ showPad 2 n ++ ": " ++ mkComment effort input1 input2 ++ ")"
showPad l n =
replicate (max 0 (l - (length sn))) '0' ++ sn
where sn = show n
inputs = zip inputs1 inputs2
_ = sample1 : inputs1
inputs1 =
map (\(g, size) -> unGen arbitrary g size) $ zip gs1 sizes
gs1 =
iterate (snd . next) $ mkStdGen 1587346765
_ = sample2 : inputs2
inputs2 =
map (\(g, size) -> unGen arbitrary g size) $ zip gs2 sizes
gs2 =
iterate (snd . next) $ mkStdGen 658246234
sizes =
concat $ map (replicate 3) $ scanl1 (*) [2,2..]
efforts =
concat $ map (replicate 10) $ effortIncrementSequence initEffort