From df559c11ca4b791d737d8d403ff355c35a5c8b3f Mon Sep 17 00:00:00 2001 From: min-nguyen Date: Mon, 2 Oct 2023 10:57:51 +0100 Subject: [PATCH] Added Test.Benchmarking.Experiment for benching pure vs effectful functions --- test/Benchmark/Experiment.purs | 88 ++++++++++++++++++++++++++++++++++ test/Main.purs | 5 +- 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 test/Benchmark/Experiment.purs diff --git a/test/Benchmark/Experiment.purs b/test/Benchmark/Experiment.purs new file mode 100644 index 000000000..415a98a0c --- /dev/null +++ b/test/Benchmark/Experiment.purs @@ -0,0 +1,88 @@ +module Test.Benchmark.PureComp + + where + +import Prelude + +import Data.JSDate (getMilliseconds, now) +import Effect (Effect) +import Effect.Class.Console (log) + +now' :: Effect Number +now' = now >>= getMilliseconds + +-- | Fibonacci as a pure function +fib :: Int -> Int +fib 0 = 0 +fib 1 = 1 +fib n = fib (n-1) + fib (n-2) + +-- | Benchmarking Fibonacci, where we let-bind its result +benchFibLetBind :: Int -> Effect Int +benchFibLetBind n = do + t1 <- now' + let m = fib n -- If `m` is not yet used + t2 <- now' + log (show (t2 - t1) <> "ms") -- prints 0.0 ms + pure m + +-- | Benchmarking Fibonacci, where we let-bind its result and log it +benchFibLetBindPrint :: Int -> Effect Int +benchFibLetBindPrint n = do + t1 <- now' + let m = fib n -- If `m` is subsequently printed + log (show m) + t2 <- now' + log (show (t2 - t1) <> "ms") -- prints correct ms + pure m + +-- | Benchmarking Fibonacci, where we monadically bind its result (using `pure`) +benchFibDoBind :: Int -> Effect Int +benchFibDoBind n = do + t1 <- now' + m <- pure $ fib n -- If `fib` is wrapped in `pure`, and the result `m` is not yet used + t2 <- now' + log (show (t2 - t1) <> "ms") -- prints 0.0 ms + pure m + +-- | Benchmarking Fibonacci, where we monadically bind its result (using `pure`) and log it +benchFibDoBindPrint :: Int -> Effect Int +benchFibDoBindPrint n = do + t1 <- now' + m <- pure $ fib n -- If `fib` is wrapped in `pure`, and the result `m` is subsequently printed + log (show m) + t2 <- now' + log (show (t2 - t1) <> "ms") -- prints correct ms + pure m + +-- | Fibonacci as an effectful function +fibm :: Int -> Effect Int +fibm 0 = pure 0 +fibm 1 = pure 1 +fibm n = do + n1 <- fibm (n-1) + n2 <- fibm (n-2) + pure (n1 + n2) + +-- | Benchmarking the effectful version of Fibonacci, where we monadically bind its result +benchFibmBind :: Int -> Effect Int +benchFibmBind n = do + t1 <- now' + m <- fibm n -- If `fib` itself is defined as an effectful computation `fibm` + t2 <- now' + log (show (t2 - t1) <> "ms") -- prints correct ms (without needing the result `m` to be used beforehand) + pure m + +benchFibs :: Effect Unit +benchFibs = do + log ("-- | Benchmarking Fibonacci, where we let-bind its result") + _ <- benchFibLetBind 40 + log ("-- | Benchmarking Fibonacci, where we let-bind its result and log it") + _ <- benchFibLetBindPrint 40 + log ("-- | Benchmarking Fibonacci, where we monadically bind its result (using `pure`)") + _ <- benchFibDoBind 40 + log ("-- | Benchmarking Fibonacci, where we monadically bind its result (using `pure`) and log it") + _ <- benchFibDoBindPrint 40 + log ("-- | Benchmarking the effectful version of Fibonacci, where we monadically bind its result") + _ <- benchFibmBind 40 + pure unit diff --git a/test/Main.purs b/test/Main.purs index bc30a4a5b..a0fa06b43 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -18,9 +18,12 @@ import Test.Many (bwdMany, linkMany, many, withDatasetMany) import Test.Spec.Mocha (run) import Test.Spec.Specs (bwd_cases, desugar_cases, graphics_cases, linking_cases, misc_cases) import Util (type (×)) +import Test.Benchmark.PureComp (benchFibs) main :: Effect Unit -main = run tests +main = do + if true then benchFibs else pure unit + run tests tests :: Array (String × Aff Unit) tests = concat