From 61604b25cfb003b1bc897f0a7663dae85f907870 Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Fri, 9 Feb 2024 17:31:25 +0100 Subject: [PATCH 1/8] use subset --- src/Juvix/Compiler/Tree/EvaluatorEff.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Juvix/Compiler/Tree/EvaluatorEff.hs b/src/Juvix/Compiler/Tree/EvaluatorEff.hs index d1f374275a..b4d7c4e9cf 100644 --- a/src/Juvix/Compiler/Tree/EvaluatorEff.hs +++ b/src/Juvix/Compiler/Tree/EvaluatorEff.hs @@ -30,7 +30,7 @@ emptyEvalCtx = eval :: (E.Output Value :> r, E.Error EvalError :> r) => InfoTable -> Node -> Eff r Value eval tab = E.runReader emptyEvalCtx . eval' where - eval' :: forall r'. (E.Output Value :> r', E.Reader EvalCtx :> r', E.Error EvalError :> r') => Node -> Eff r' Value + eval' :: forall r'. (E.Subset '[E.Output Value, E.Reader EvalCtx, E.Error EvalError] r') => Node -> Eff r' Value eval' node = case node of Binop x -> goBinop x Unop x -> goUnop x From 49ed2dc81fabf557315480c09c7c0b90bc4e472d Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Fri, 9 Feb 2024 17:31:37 +0100 Subject: [PATCH 2/8] add benchmarks --- bench/Main.hs | 2 +- bench2/Benchmark/Output.hs | 51 ++++++++++++++++++++++++ bench2/Benchmark/State.hs | 60 +++++++++++++++++++++++++++++ bench2/Main.hs | 13 +++++++ package.yaml | 9 +++++ src/Juvix/Prelude/Effects.hs | 2 + src/Juvix/Prelude/Effects/Accum.hs | 3 ++ src/Juvix/Prelude/Effects/Output.hs | 5 ++- 8 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 bench2/Benchmark/Output.hs create mode 100644 bench2/Benchmark/State.hs create mode 100644 bench2/Main.hs diff --git a/bench/Main.hs b/bench/Main.hs index d329095c69..7a3e64f242 100644 --- a/bench/Main.hs +++ b/bench/Main.hs @@ -105,7 +105,7 @@ csvRules s = | (v, r) <- zipExact (s ^. suiteVariants) rows ] header' = "Color," <> header - writeFile (toFilePath csv) (Text.unlines (header' : rows')) + writeFileEnsureLn csv (Text.unlines (header' : rows')) fromSuite :: Suite -> [Benchmark] fromSuite s = map go (s ^. suiteVariants) diff --git a/bench2/Benchmark/Output.hs b/bench2/Benchmark/Output.hs new file mode 100644 index 0000000000..ba82a1cf08 --- /dev/null +++ b/bench2/Benchmark/Output.hs @@ -0,0 +1,51 @@ +module Benchmark.Output where + +import Juvix.Prelude +import Juvix.Prelude.Effects (Eff, (:>)) +import Juvix.Prelude.Effects qualified as E +import Test.Tasty.Bench + +bm :: Benchmark +bm = + bgroup + "Output" + [ bench "Eff Output (Dynamic)" $ nf countdownEff k, + bench "Eff Accum (Static)" $ nf countdownAccum k, + bench "Sem Output" $ nf countdownSem k, + bench "Raw Output" $ nf countdownRaw k + ] + +k :: Natural +k = 2 ^ (22 :: Natural) + +countdownRaw :: Natural -> Natural +countdownRaw = sum' . reverse . go [] + where + go :: [Natural] -> Natural -> [Natural] + go acc = \case + 0 -> acc + m -> go (m : acc) (pred m) + +countdownAccum :: Natural -> Natural +countdownAccum = sum' . E.runPureEff . E.execAccumList . go + where + go :: (E.Accum Natural :> r) => Natural -> Eff r () + go = \case + 0 -> return () + m -> E.accum m >> go (pred m) + +countdownEff :: Natural -> Natural +countdownEff = sum' . E.runPureEff . E.execOutputList . go + where + go :: (E.Output Natural :> r) => Natural -> Eff r () + go = \case + 0 -> return () + m -> E.output m >> go (pred m) + +countdownSem :: Natural -> Natural +countdownSem = sum' . run . execOutputList . go + where + go :: (Members '[Output Natural] r) => Natural -> Sem r () + go = \case + 0 -> return () + m -> output m >> go (pred m) diff --git a/bench2/Benchmark/State.hs b/bench2/Benchmark/State.hs new file mode 100644 index 0000000000..1a87c642fc --- /dev/null +++ b/bench2/Benchmark/State.hs @@ -0,0 +1,60 @@ +module Benchmark.State where + +import Juvix.Prelude +import Juvix.Prelude.Effects (Eff, (:>)) +import Juvix.Prelude.Effects qualified as E +import Test.Tasty.Bench + +data St = St + { _stA :: Natural, + _stB :: Natural + } + +makeLenses ''St + +bm :: Benchmark +bm = + bgroup + "State" + [ bench "Eff State (Static)" $ nf countEff k, + bench "Sem State" $ nf countSem k, + bench "Raw State" $ nf countRaw k + ] + +k :: Natural +k = 2 ^ (21 :: Natural) + +addSt :: St -> Natural +addSt (St a b) = a + b + +emptySt :: St +emptySt = St 0 0 + +l :: Bool -> Lens' St Natural +l b + | b = stA + | otherwise = stB + +countRaw :: Natural -> Natural +countRaw = addSt . go emptySt + where + go :: St -> Natural -> St + go acc = \case + 0 -> acc + m -> go (over (l (even m)) (+ m) acc) (pred m) + +countEff :: Natural -> Natural +countEff = addSt . E.runPureEff . E.execState emptySt . go + where + go :: (E.State St :> r) => Natural -> Eff r () + go = \case + 0 -> return () + m -> E.modify (over (l (even m)) (+ m)) >> go (pred m) + +countSem :: Natural -> Natural +countSem = addSt . run . execState emptySt . go + where + go :: (Members '[State St] r) => Natural -> Sem r () + go = \case + 0 -> return () + m -> modify (over (l (even m)) (+ m)) >> go (pred m) diff --git a/bench2/Main.hs b/bench2/Main.hs new file mode 100644 index 0000000000..5911bddf94 --- /dev/null +++ b/bench2/Main.hs @@ -0,0 +1,13 @@ +module Main where + +import Benchmark.Output qualified as Output +import Benchmark.State qualified as State +import Juvix.Prelude +import Test.Tasty.Bench + +main :: IO () +main = + defaultMain + [ Output.bm, + State.bm + ] diff --git a/package.yaml b/package.yaml index c4b3126ec7..d2402bf6f5 100644 --- a/package.yaml +++ b/package.yaml @@ -162,6 +162,15 @@ library: default-language: GHC2021 executables: + juvixbench: + main: Main.hs + source-dirs: bench2 + dependencies: + - juvix + - tasty-bench == 0.3.* + verbatim: + default-language: GHC2021 + juvix: main: Main.hs source-dirs: app diff --git a/src/Juvix/Prelude/Effects.hs b/src/Juvix/Prelude/Effects.hs index 0659c97731..67cff4a905 100644 --- a/src/Juvix/Prelude/Effects.hs +++ b/src/Juvix/Prelude/Effects.hs @@ -1,8 +1,10 @@ module Juvix.Prelude.Effects ( module Juvix.Prelude.Effects.Output, module Juvix.Prelude.Effects.Base, + module Juvix.Prelude.Effects.Accum, ) where +import Juvix.Prelude.Effects.Accum import Juvix.Prelude.Effects.Base import Juvix.Prelude.Effects.Output diff --git a/src/Juvix/Prelude/Effects/Accum.hs b/src/Juvix/Prelude/Effects/Accum.hs index f284556e94..076967ba67 100644 --- a/src/Juvix/Prelude/Effects/Accum.hs +++ b/src/Juvix/Prelude/Effects/Accum.hs @@ -17,6 +17,9 @@ runAccumList m = do (a, Accum s) <- runStaticRep (Accum mempty) m return (reverse s, a) +execAccumList :: Eff (Accum o ': r) a -> Eff r [o] +execAccumList = fmap fst . runAccumList + ignoreAccum :: Eff (Accum o ': r) a -> Eff r a ignoreAccum m = snd <$> runAccumList m diff --git a/src/Juvix/Prelude/Effects/Output.hs b/src/Juvix/Prelude/Effects/Output.hs index 8ec8da15d1..0758685b4d 100644 --- a/src/Juvix/Prelude/Effects/Output.hs +++ b/src/Juvix/Prelude/Effects/Output.hs @@ -4,7 +4,7 @@ module Juvix.Prelude.Effects.Output where import Data.Kind qualified as GHC import Effectful.Dispatch.Dynamic -import Juvix.Prelude.Base hiding (Effect, Output, interpret, output, reinterpret, runOutputList) +import Juvix.Prelude.Base hiding (Effect, Output, State, interpret, modify, output, reinterpret, runOutputList, runState) import Juvix.Prelude.Effects.Accum import Juvix.Prelude.Effects.Base @@ -22,6 +22,9 @@ runOutputList :: Eff (Output o ': r) a -> Eff r ([o], a) runOutputList = reinterpret runAccumList $ \_ -> \case Output x -> accum x +execOutputList :: Eff (Output o ': r) a -> Eff r [o] +execOutputList = fmap fst . runOutputList + ignoreOutput :: Eff (Output o ': r) a -> Eff r a ignoreOutput = interpret $ \_ -> \case Output {} -> return () From 0ef01a0dae5e2f2a7f686e6c0b84f4d0f18807fb Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Fri, 9 Feb 2024 17:37:39 +0100 Subject: [PATCH 3/8] Revert "use subset" This reverts commit d8edd8023e47bce050805f20de2a07aa6f9a2110. --- src/Juvix/Compiler/Tree/EvaluatorEff.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Juvix/Compiler/Tree/EvaluatorEff.hs b/src/Juvix/Compiler/Tree/EvaluatorEff.hs index b4d7c4e9cf..d1f374275a 100644 --- a/src/Juvix/Compiler/Tree/EvaluatorEff.hs +++ b/src/Juvix/Compiler/Tree/EvaluatorEff.hs @@ -30,7 +30,7 @@ emptyEvalCtx = eval :: (E.Output Value :> r, E.Error EvalError :> r) => InfoTable -> Node -> Eff r Value eval tab = E.runReader emptyEvalCtx . eval' where - eval' :: forall r'. (E.Subset '[E.Output Value, E.Reader EvalCtx, E.Error EvalError] r') => Node -> Eff r' Value + eval' :: forall r'. (E.Output Value :> r', E.Reader EvalCtx :> r', E.Error EvalError :> r') => Node -> Eff r' Value eval' node = case node of Binop x -> goBinop x Unop x -> goUnop x From 25262b987b449a887fef0ba98ca03850b12ba479 Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Fri, 9 Feb 2024 18:50:06 +0100 Subject: [PATCH 4/8] reader benchmark --- bench2/Benchmark/Effect.hs | 17 +++++++++ bench2/Benchmark/{ => Effect}/Output.hs | 2 +- bench2/Benchmark/Effect/Reader.hs | 50 +++++++++++++++++++++++++ bench2/Benchmark/Effect/ReaderH.hs | 46 +++++++++++++++++++++++ bench2/Benchmark/{ => Effect}/State.hs | 2 +- bench2/Main.hs | 6 +-- 6 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 bench2/Benchmark/Effect.hs rename bench2/Benchmark/{ => Effect}/Output.hs (97%) create mode 100644 bench2/Benchmark/Effect/Reader.hs create mode 100644 bench2/Benchmark/Effect/ReaderH.hs rename bench2/Benchmark/{ => Effect}/State.hs (97%) diff --git a/bench2/Benchmark/Effect.hs b/bench2/Benchmark/Effect.hs new file mode 100644 index 0000000000..2f8e19d902 --- /dev/null +++ b/bench2/Benchmark/Effect.hs @@ -0,0 +1,17 @@ +module Benchmark.Effect where + +import Benchmark.Effect.Output qualified as Output +import Benchmark.Effect.Reader qualified as Reader +import Benchmark.Effect.ReaderH qualified as ReaderH +import Benchmark.Effect.State qualified as State +import Test.Tasty.Bench + +bm :: Benchmark +bm = + bgroup + "Effect" + [ Output.bm, + State.bm, + ReaderH.bm, + Reader.bm + ] diff --git a/bench2/Benchmark/Output.hs b/bench2/Benchmark/Effect/Output.hs similarity index 97% rename from bench2/Benchmark/Output.hs rename to bench2/Benchmark/Effect/Output.hs index ba82a1cf08..4789f049ce 100644 --- a/bench2/Benchmark/Output.hs +++ b/bench2/Benchmark/Effect/Output.hs @@ -1,4 +1,4 @@ -module Benchmark.Output where +module Benchmark.Effect.Output where import Juvix.Prelude import Juvix.Prelude.Effects (Eff, (:>)) diff --git a/bench2/Benchmark/Effect/Reader.hs b/bench2/Benchmark/Effect/Reader.hs new file mode 100644 index 0000000000..5d98f0ce3c --- /dev/null +++ b/bench2/Benchmark/Effect/Reader.hs @@ -0,0 +1,50 @@ +module Benchmark.Effect.Reader where + +import Juvix.Prelude +import Juvix.Prelude.Effects (Eff, (:>)) +import Juvix.Prelude.Effects qualified as E +import Test.Tasty.Bench + +bm :: Benchmark +bm = + bgroup + "Reader (First order)" + [ bench "Eff Reader (Static)" $ nf countEff k, + bench "Sem Reader" $ nf countSem k, + bench "Raw Reader" $ nf countRaw k + ] + +k :: Natural +k = 2 ^ (21 :: Natural) + +c :: Natural +c = 5 + +countRaw :: Natural -> Natural +countRaw = sum' . go [] + where + i :: Natural = 5 + go :: [Natural] -> Natural -> [Natural] + go acc = \case + 0 -> acc + m -> go (i : acc) (pred m) + +countEff :: Natural -> Natural +countEff = sum' . E.runPureEff . E.runReader c . go [] + where + go :: (E.Reader Natural :> r) => [Natural] -> Natural -> Eff r [Natural] + go acc = \case + 0 -> return acc + n -> do + i <- E.ask + go (i : acc) (pred n) + +countSem :: Natural -> Natural +countSem = sum' . run . runReader c . go [] + where + go :: (Member (Reader Natural) r) => [Natural] -> Natural -> Sem r [Natural] + go acc = \case + 0 -> return acc + n -> do + i <- ask + go (i : acc) (pred n) diff --git a/bench2/Benchmark/Effect/ReaderH.hs b/bench2/Benchmark/Effect/ReaderH.hs new file mode 100644 index 0000000000..e6a0d73d8a --- /dev/null +++ b/bench2/Benchmark/Effect/ReaderH.hs @@ -0,0 +1,46 @@ +module Benchmark.Effect.ReaderH where + +import Juvix.Prelude +import Juvix.Prelude.Effects (Eff, (:>)) +import Juvix.Prelude.Effects qualified as E +import Test.Tasty.Bench + +bm :: Benchmark +bm = + bgroup + "Reader (Higher order)" + [ bench "Eff Reader (Static)" $ nf countEff k, + bench "Sem Reader" $ nf countSem k, + bench "Raw Reader" $ nf countRaw k + ] + +k :: Natural +k = 2 ^ (21 :: Natural) + +countRaw :: Natural -> Natural +countRaw = sum' . go [] + where + go :: [Natural] -> Natural -> [Natural] + go acc = \case + 0 -> acc + m -> go (m : acc) (pred m) + +countEff :: Natural -> Natural +countEff x = sum' . E.runPureEff . E.runReader x $ go [] + where + go :: (E.Reader Natural :> r) => [Natural] -> Eff r [Natural] + go acc = do + n <- E.ask + case n of + 0 -> return acc + m -> E.local @Natural pred (go (m : acc)) + +countSem :: Natural -> Natural +countSem x = sum . run . runReader x $ go [] + where + go :: (Members '[Reader Natural] r) => [Natural] -> Sem r [Natural] + go acc = do + n :: Natural <- ask + case n of + 0 -> return acc + m -> local @Natural pred (go (m : acc)) diff --git a/bench2/Benchmark/State.hs b/bench2/Benchmark/Effect/State.hs similarity index 97% rename from bench2/Benchmark/State.hs rename to bench2/Benchmark/Effect/State.hs index 1a87c642fc..f940c6913b 100644 --- a/bench2/Benchmark/State.hs +++ b/bench2/Benchmark/Effect/State.hs @@ -1,4 +1,4 @@ -module Benchmark.State where +module Benchmark.Effect.State where import Juvix.Prelude import Juvix.Prelude.Effects (Eff, (:>)) diff --git a/bench2/Main.hs b/bench2/Main.hs index 5911bddf94..d32513e145 100644 --- a/bench2/Main.hs +++ b/bench2/Main.hs @@ -1,13 +1,11 @@ module Main where -import Benchmark.Output qualified as Output -import Benchmark.State qualified as State +import Benchmark.Effect qualified as Effect import Juvix.Prelude import Test.Tasty.Bench main :: IO () main = defaultMain - [ Output.bm, - State.bm + [ Effect.bm ] From 5c163bae92c45405c5ffdddcf5eeba1faf8acf26 Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Mon, 12 Feb 2024 12:54:31 +0100 Subject: [PATCH 5/8] benchmark embed IO --- bench2/Benchmark/Effect.hs | 2 ++ bench2/Benchmark/Effect/EmbedIO.hs | 49 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 bench2/Benchmark/Effect/EmbedIO.hs diff --git a/bench2/Benchmark/Effect.hs b/bench2/Benchmark/Effect.hs index 2f8e19d902..d59635de71 100644 --- a/bench2/Benchmark/Effect.hs +++ b/bench2/Benchmark/Effect.hs @@ -1,5 +1,6 @@ module Benchmark.Effect where +import Benchmark.Effect.EmbedIO qualified as EmbedIO import Benchmark.Effect.Output qualified as Output import Benchmark.Effect.Reader qualified as Reader import Benchmark.Effect.ReaderH qualified as ReaderH @@ -13,5 +14,6 @@ bm = [ Output.bm, State.bm, ReaderH.bm, + EmbedIO.bm, Reader.bm ] diff --git a/bench2/Benchmark/Effect/EmbedIO.hs b/bench2/Benchmark/Effect/EmbedIO.hs new file mode 100644 index 0000000000..8d01b06a27 --- /dev/null +++ b/bench2/Benchmark/Effect/EmbedIO.hs @@ -0,0 +1,49 @@ +module Benchmark.Effect.EmbedIO where + +import Juvix.Prelude +import Juvix.Prelude.Effects (Eff) +import Juvix.Prelude.Effects qualified as E +import Test.Tasty.Bench + +bm :: Benchmark +bm = + bgroup + "Embed IO" + [ bench "Raw IO" $ nfAppIO countRaw k, + bench "Eff RIO" $ nfAppIO countEff k, + bench "Sem Embed IO" $ nfAppIO countSem k + ] + +k :: Natural +k = 2 ^ (23 :: Natural) + +c :: Char +c = 'x' + +countRaw :: Natural -> IO () +countRaw = countHelper + +countHelper :: forall m. (MonadMask m, MonadIO m) => Natural -> m () +countHelper n = + withSystemTempFile "tmp" $ \_ h -> go h n + where + go :: Handle -> Natural -> m () + go h = \case + 0 -> return () + a -> liftIO (hPutChar h c) >> go h (pred a) + +countSem :: Natural -> IO () +countSem n = withSystemTempFile "tmp" $ \_ h -> runM (go h n) + where + go :: Handle -> Natural -> Sem '[Embed IO] () + go h = \case + 0 -> return () + a -> liftIO (hPutChar h c) >> go h (pred a) + +countEff :: Natural -> IO () +countEff n = withSystemTempFile "tmp" $ \_ h -> E.runEff (go h n) + where + go :: Handle -> Natural -> Eff '[E.IOE] () + go h = \case + 0 -> return () + a -> liftIO (hPutChar h c) >> go h (pred a) From 3f74450e1ac8a60c0b691207bb7afc95d6b36ff3 Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Mon, 12 Feb 2024 19:17:46 +0100 Subject: [PATCH 6/8] simplify --- bench2/Benchmark/Effect/Reader.hs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bench2/Benchmark/Effect/Reader.hs b/bench2/Benchmark/Effect/Reader.hs index 5d98f0ce3c..c2c5220448 100644 --- a/bench2/Benchmark/Effect/Reader.hs +++ b/bench2/Benchmark/Effect/Reader.hs @@ -23,11 +23,10 @@ c = 5 countRaw :: Natural -> Natural countRaw = sum' . go [] where - i :: Natural = 5 go :: [Natural] -> Natural -> [Natural] go acc = \case 0 -> acc - m -> go (i : acc) (pred m) + m -> go (c : acc) (pred m) countEff :: Natural -> Natural countEff = sum' . E.runPureEff . E.runReader c . go [] From 3f5cccde631a141c3a327704d5af0a7a826a0a12 Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Mon, 12 Feb 2024 19:17:52 +0100 Subject: [PATCH 7/8] simplify State test --- bench2/Benchmark/Effect/State.hs | 38 +++++++++----------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/bench2/Benchmark/Effect/State.hs b/bench2/Benchmark/Effect/State.hs index f940c6913b..6424bf8391 100644 --- a/bench2/Benchmark/Effect/State.hs +++ b/bench2/Benchmark/Effect/State.hs @@ -5,13 +5,6 @@ import Juvix.Prelude.Effects (Eff, (:>)) import Juvix.Prelude.Effects qualified as E import Test.Tasty.Bench -data St = St - { _stA :: Natural, - _stB :: Natural - } - -makeLenses ''St - bm :: Benchmark bm = bgroup @@ -22,39 +15,28 @@ bm = ] k :: Natural -k = 2 ^ (21 :: Natural) - -addSt :: St -> Natural -addSt (St a b) = a + b - -emptySt :: St -emptySt = St 0 0 - -l :: Bool -> Lens' St Natural -l b - | b = stA - | otherwise = stB +k = 2 ^ (22 :: Natural) countRaw :: Natural -> Natural -countRaw = addSt . go emptySt +countRaw = go 0 where - go :: St -> Natural -> St + go :: Natural -> Natural -> Natural go acc = \case 0 -> acc - m -> go (over (l (even m)) (+ m) acc) (pred m) + m -> go (acc + m) (pred m) countEff :: Natural -> Natural -countEff = addSt . E.runPureEff . E.execState emptySt . go +countEff = E.runPureEff . E.execState 0 . go where - go :: (E.State St :> r) => Natural -> Eff r () + go :: (E.State Natural :> r) => Natural -> Eff r () go = \case 0 -> return () - m -> E.modify (over (l (even m)) (+ m)) >> go (pred m) + m -> E.modify (+ m) >> go (pred m) countSem :: Natural -> Natural -countSem = addSt . run . execState emptySt . go +countSem = run . execState 0 . go where - go :: (Members '[State St] r) => Natural -> Sem r () + go :: (Members '[State Natural] r) => Natural -> Sem r () go = \case 0 -> return () - m -> modify (over (l (even m)) (+ m)) >> go (pred m) + m -> modify (+ m) >> go (pred m) From 3ed76a0922dcb23deb8c993777cfafad1ad6fe0c Mon Sep 17 00:00:00 2001 From: Jan Mas Rovira Date: Mon, 12 Feb 2024 19:36:32 +0100 Subject: [PATCH 8/8] simplify IO --- bench2/Benchmark/Effect/EmbedIO.hs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/bench2/Benchmark/Effect/EmbedIO.hs b/bench2/Benchmark/Effect/EmbedIO.hs index 8d01b06a27..494edc69e9 100644 --- a/bench2/Benchmark/Effect/EmbedIO.hs +++ b/bench2/Benchmark/Effect/EmbedIO.hs @@ -21,16 +21,13 @@ c :: Char c = 'x' countRaw :: Natural -> IO () -countRaw = countHelper - -countHelper :: forall m. (MonadMask m, MonadIO m) => Natural -> m () -countHelper n = +countRaw n = withSystemTempFile "tmp" $ \_ h -> go h n where - go :: Handle -> Natural -> m () + go :: Handle -> Natural -> IO () go h = \case 0 -> return () - a -> liftIO (hPutChar h c) >> go h (pred a) + a -> hPutChar h c >> go h (pred a) countSem :: Natural -> IO () countSem n = withSystemTempFile "tmp" $ \_ h -> runM (go h n)