eproc

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

commit b0fe75351d6a55ecbd90e4f95b7af53ebd58c5ef
parent 5c12e9d87bdd71a96170381c6fceaefb371ce395
Author: Jared Tobin <jared@jtobin.io>
Date:   Fri,  3 Jul 2026 14:30:42 -0230

bench: ConfSeq update and fold benchmarks

One-step update and 1000-sample fold at g = 200, in both the
criterion and weigh suites. The NFData orphan for ConfSeq.State
relies on the module's invariant that the live-candidate list is
fully forced on construction, so WHNF == NF.

Diffstat:
Mbench/Main.hs | 26++++++++++++++++++++++++++
Mbench/Weight.hs | 23+++++++++++++++++++++++
2 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/bench/Main.hs b/bench/Main.hs @@ -7,6 +7,7 @@ import Control.DeepSeq import qualified Numeric.Eproc.Bernoulli as Bern import qualified Numeric.Eproc.Bernoulli.TwoSided as BernTS import qualified Numeric.Eproc.Bounded as Bounded +import qualified Numeric.Eproc.ConfSeq as CS import qualified Numeric.Eproc.Paired as P import Criterion.Main @@ -35,6 +36,8 @@ main = defaultMain [ , bern_stream , bern_ts_update , bern_ts_stream + , confseq_update + , confseq_stream ] update :: Benchmark @@ -139,3 +142,26 @@ bern_ts_stream = , bench "adaptive" $ nf (run_b cfg_a) xs , bench "newton" $ nf (run_b cfg_o) xs ] + +-- ConfSeq.State carries a list of live grid candidates rather than +-- only unboxed fields, but 'initial' and 'update' construct that +-- list fully forced, so WHNF == NF holds here by construction too. +instance NFData CS.State where rnf !_ = () + +confseq_update :: Benchmark +confseq_update = + let !cfg = ok (CS.config 0.0 1.0 0.05 200) + !st = CS.initial cfg + !x = 0.7 + in bgroup "ConfSeq.update (one step, g = 200)" [ + bench "plug-in" $ nf (CS.update cfg st) x + ] + +confseq_stream :: Benchmark +confseq_stream = + let !xs = force (take 1000 (cycle [0.3, 0.7])) + !cfg = ok (CS.config 0.0 1.0 0.05 200) + run_c = foldl' (CS.update cfg) (CS.initial cfg) + in bgroup "ConfSeq.update (1000-sample fold, g = 200)" [ + bench "plug-in" $ nf run_c xs + ] diff --git a/bench/Weight.hs b/bench/Weight.hs @@ -7,6 +7,7 @@ import Control.DeepSeq import qualified Numeric.Eproc.Bernoulli as Bern import qualified Numeric.Eproc.Bernoulli.TwoSided as BernTS import qualified Numeric.Eproc.Bounded as Bounded +import qualified Numeric.Eproc.ConfSeq as CS import qualified Numeric.Eproc.Paired as P import Weigh @@ -32,6 +33,8 @@ main = mainWith $ do bern_stream bern_ts_update bern_ts_stream + confseq_update + confseq_stream update :: Weigh () update = @@ -126,3 +129,23 @@ bern_ts_stream = func "fixed" (run_b cfg_f) xs func "adaptive" (run_b cfg_a) xs func "newton" (run_b cfg_o) xs + +-- ConfSeq.State carries a list of live grid candidates rather than +-- only unboxed fields, but 'initial' and 'update' construct that +-- list fully forced, so WHNF == NF holds here by construction too. +instance NFData CS.State where rnf !_ = () + +confseq_update :: Weigh () +confseq_update = + let !cfg = ok (CS.config 0.0 1.0 0.05 200) + !st = CS.initial cfg + in wgroup "ConfSeq.update (one step, g = 200)" $ do + func "plug-in" (CS.update cfg st) 0.7 + +confseq_stream :: Weigh () +confseq_stream = + let !xs = force (take 1000 (cycle [0.3, 0.7])) + !cfg = ok (CS.config 0.0 1.0 0.05 200) + run_c = foldl' (CS.update cfg) (CS.initial cfg) + in wgroup "ConfSeq.update (1000-sample fold, g = 200)" $ do + func "plug-in" run_c xs