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:
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