eproc

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit f1318f8b4511eae8fe5cbe9af2ab6b988c091dd2
parent f47c6310e1bc44f8a0213beeac799ec75cc4d2b6
Author: Jared Tobin <jared@jtobin.io>
Date:   Tue,  2 Jun 2026 20:47:24 -0230

bench: add suite

Diffstat:
Abench/Main.hs | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abench/Weight.hs | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mppad-eproc.cabal | 34++++++++++++++++++++++++++++++++++
3 files changed, 198 insertions(+), 0 deletions(-)

diff --git a/bench/Main.hs b/bench/Main.hs @@ -0,0 +1,86 @@ +{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-type-defaults #-} +{-# LANGUAGE BangPatterns #-} + +module Main where + +import Control.DeepSeq +import qualified Statistics.EProcess as E +import qualified Statistics.EProcess.Bettor as B +import qualified Statistics.EProcess.Mean as M +import qualified Statistics.EProcess.TwoSample as TS +import Criterion.Main + +-- all relevant fields are strict (and UNPACK'd for the doubles), so +-- WHNF == NF for these types. orphan instances keep the library API +-- untouched. +instance NFData B.AGRAPA where rnf !_ = () +instance NFData B.ONS where rnf !_ = () +instance NFData (M.State s) where rnf !_ = () +instance NFData (TS.State s) where rnf !_ = () +instance NFData M.Verdict where rnf !_ = () + +main :: IO () +main = defaultMain [ + update + , decide + , stream + , twosample + ] + +update :: Benchmark +update = + let !cfgF = M.config 0.5 0.0 1.0 1.0e-3 (const (E.fixed 0.5)) + :: M.Config () + !cfgA = M.config 0.5 0.0 1.0 1.0e-3 E.agrapa + :: M.Config B.AGRAPA + !cfgO = M.config 0.5 0.0 1.0 1.0e-3 E.ons + :: M.Config B.ONS + !stF = M.initial cfgF + !stA = M.initial cfgA + !stO = M.initial cfgO + !x = 0.7 + in bgroup "Mean.update (one step)" [ + bench "fixed" $ nf (M.update cfgF stF) x + , bench "agrapa" $ nf (M.update cfgA stA) x + , bench "ons" $ nf (M.update cfgO stO) x + ] + +decide :: Benchmark +decide = + let !cfg = M.config 0.5 0.0 1.0 1.0e-3 E.ons :: M.Config B.ONS + !st = M.initial cfg + in bgroup "Mean.decide" [ + bench "initial state" $ nf (M.decide cfg) st + ] + +stream :: Benchmark +stream = + let !xs = force (take 1000 (cycle [0.3, 0.7])) + !cfgF = M.config 0.5 0.0 1.0 1.0e-3 (const (E.fixed 0.5)) + :: M.Config () + !cfgA = M.config 0.5 0.0 1.0 1.0e-3 E.agrapa + :: M.Config B.AGRAPA + !cfgO = M.config 0.5 0.0 1.0 1.0e-3 E.ons + :: M.Config B.ONS + runM cfg = foldl' (M.update cfg) (M.initial cfg) + in bgroup "Mean.update (1000-sample fold)" [ + bench "fixed" $ nf (runM cfgF) xs + , bench "agrapa" $ nf (runM cfgA) xs + , bench "ons" $ nf (runM cfgO) xs + ] + +twosample :: Benchmark +twosample = + let !ps = force (take 1000 (cycle [(0.3, 0.7), (0.7, 0.3)])) + !cfgF = TS.config 0.0 1.0 1.0e-3 (const (E.fixed 0.5)) + :: TS.Config () + !cfgA = TS.config 0.0 1.0 1.0e-3 E.agrapa + :: TS.Config B.AGRAPA + !cfgO = TS.config 0.0 1.0 1.0e-3 E.ons + :: TS.Config B.ONS + runT cfg = foldl' (TS.update cfg) (TS.initial cfg) + in bgroup "TwoSample.update (1000-sample fold)" [ + bench "fixed" $ nf (runT cfgF) ps + , bench "agrapa" $ nf (runT cfgA) ps + , bench "ons" $ nf (runT cfgO) ps + ] diff --git a/bench/Weight.hs b/bench/Weight.hs @@ -0,0 +1,78 @@ +{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-type-defaults #-} +{-# LANGUAGE BangPatterns #-} + +module Main where + +import Control.DeepSeq +import qualified Statistics.EProcess as E +import qualified Statistics.EProcess.Bettor as B +import qualified Statistics.EProcess.Mean as M +import qualified Statistics.EProcess.TwoSample as TS +import Weigh + +instance NFData B.AGRAPA where rnf !_ = () +instance NFData B.ONS where rnf !_ = () +instance NFData (M.State s) where rnf !_ = () +instance NFData (TS.State s) where rnf !_ = () +instance NFData M.Verdict where rnf !_ = () + +-- note that 'weigh' doesn't work properly in a repl +main :: IO () +main = mainWith $ do + update + decide + stream + twosample + +update :: Weigh () +update = + let !cfgF = M.config 0.5 0.0 1.0 1.0e-3 (const (E.fixed 0.5)) + :: M.Config () + !cfgA = M.config 0.5 0.0 1.0 1.0e-3 E.agrapa + :: M.Config B.AGRAPA + !cfgO = M.config 0.5 0.0 1.0 1.0e-3 E.ons + :: M.Config B.ONS + !stF = M.initial cfgF + !stA = M.initial cfgA + !stO = M.initial cfgO + in wgroup "Mean.update (one step)" $ do + func "fixed" (M.update cfgF stF) 0.7 + func "agrapa" (M.update cfgA stA) 0.7 + func "ons" (M.update cfgO stO) 0.7 + +decide :: Weigh () +decide = + let !cfg = M.config 0.5 0.0 1.0 1.0e-3 E.ons :: M.Config B.ONS + !st = M.initial cfg + in wgroup "Mean.decide" $ do + func "initial state" (M.decide cfg) st + +stream :: Weigh () +stream = + let !xs = force (take 1000 (cycle [0.3, 0.7])) + !cfgF = M.config 0.5 0.0 1.0 1.0e-3 (const (E.fixed 0.5)) + :: M.Config () + !cfgA = M.config 0.5 0.0 1.0 1.0e-3 E.agrapa + :: M.Config B.AGRAPA + !cfgO = M.config 0.5 0.0 1.0 1.0e-3 E.ons + :: M.Config B.ONS + runM cfg = foldl' (M.update cfg) (M.initial cfg) + in wgroup "Mean.update (1000-sample fold)" $ do + func "fixed" (runM cfgF) xs + func "agrapa" (runM cfgA) xs + func "ons" (runM cfgO) xs + +twosample :: Weigh () +twosample = + let !ps = force (take 1000 (cycle [(0.3, 0.7), (0.7, 0.3)])) + !cfgF = TS.config 0.0 1.0 1.0e-3 (const (E.fixed 0.5)) + :: TS.Config () + !cfgA = TS.config 0.0 1.0 1.0e-3 E.agrapa + :: TS.Config B.AGRAPA + !cfgO = TS.config 0.0 1.0 1.0e-3 E.ons + :: TS.Config B.ONS + runT cfg = foldl' (TS.update cfg) (TS.initial cfg) + in wgroup "TwoSample.update (1000-sample fold)" $ do + func "fixed" (runT cfgF) ps + func "agrapa" (runT cfgA) ps + func "ons" (runT cfgO) ps diff --git a/ppad-eproc.cabal b/ppad-eproc.cabal @@ -56,3 +56,37 @@ test-suite eproc-tests , tasty , tasty-hunit , tasty-quickcheck + +benchmark eproc-bench + type: exitcode-stdio-1.0 + default-language: Haskell2010 + hs-source-dirs: bench + main-is: Main.hs + + ghc-options: + -rtsopts -O2 -Wall -fno-warn-orphans + if flag(llvm) + ghc-options: -fllvm + + build-depends: + base + , criterion + , deepseq + , ppad-eproc + +benchmark eproc-weigh + type: exitcode-stdio-1.0 + default-language: Haskell2010 + hs-source-dirs: bench + main-is: Weight.hs + + ghc-options: + -rtsopts -O2 -Wall -fno-warn-orphans + if flag(llvm) + ghc-options: -fllvm + + build-depends: + base + , deepseq + , ppad-eproc + , weigh