on master help sign in
Benchmark all variants of the State effect
c49ee87Andrzej Rybczak
bench/Countdown.hs+55−11
@@ -3,30 +3,37 @@ module Countdown where
3
3
4import Data.Functor.Identity
4import Data.Functor.Identity
5
5
6−import qualified Control.Monad.Reader as M
6+-- eff
7+#ifdef VERSION_eff
7−import qualified Control.Monad.State as M
8+import qualified Control.Effect as L
9+#endif
8
10
11+-- effective
9import qualified Effective as E
12import qualified Effective as E
10import qualified Effective.Reader as E
13import qualified Effective.Reader as E
11import qualified Effective.State as E
14import qualified Effective.State as E
15+import qualified Effective.State.MVar as ME
12import qualified Effective.State.Dynamic as DE
16import qualified Effective.State.Dynamic as DE
13
17
18+-- freer-simple
14#ifdef VERSION_freer_simple
19#ifdef VERSION_freer_simple
15import qualified Control.Monad.Freer as FS
20import qualified Control.Monad.Freer as FS
16import qualified Control.Monad.Freer.Reader as FS
21import qualified Control.Monad.Freer.Reader as FS
17import qualified Control.Monad.Freer.State as FS
22import qualified Control.Monad.Freer.State as FS
18#endif
23#endif
19
24
20−#ifdef VERSION_eff
25+-- fused-effects
21−import qualified Control.Effect as L
22−#endif
23−
24#ifdef VERSION_fused_effects
26#ifdef VERSION_fused_effects
25import qualified Control.Algebra as FE
27import qualified Control.Algebra as FE
26import qualified Control.Carrier.Reader as FE
28import qualified Control.Carrier.Reader as FE
27import qualified Control.Carrier.State.Strict as FE
29import qualified Control.Carrier.State.Strict as FE
28#endif
30#endif
29
31
32+-- mtl
33+import qualified Control.Monad.Reader as M
34+import qualified Control.Monad.State as M
35+
36+-- polysemy
30#ifdef VERSION_polysemy
37#ifdef VERSION_polysemy
31import qualified Polysemy as P
38import qualified Polysemy as P
32import qualified Polysemy.Reader as P
39import qualified Polysemy.Reader as P
@@ -66,7 +73,7 @@ countdownMtlDeep n = runIdentity
66 runR = flip M.runReaderT ()
73 runR = flip M.runReaderT ()
67
74
68----------------------------------------
75----------------------------------------
69−-- effective (static)
76+-- effective (pure)
70
77
71programEffectiveStatic :: E.State Integer E.:> es => E.Eff es Integer
78programEffectiveStatic :: E.State Integer E.:> es => E.Eff es Integer
72programEffectiveStatic = do
79programEffectiveStatic = do
@@ -90,6 +97,31 @@ countdownEffectiveStaticDeep n = E.runEff
90 where
97 where
91 runR = E.runReader ()
98 runR = E.runReader ()
92
99
100+----------------------------------------
101+-- effective (mvar)
102+
103+programEffectiveMVar :: ME.State Integer E.:> es => E.Eff es Integer
104+programEffectiveMVar = do
105+ n <- ME.get @Integer
106+ if n <= 0
107+ then pure n
108+ else do
109+ ME.put (n - 1)
110+ programEffectiveMVar
111+{-# NOINLINE programEffectiveMVar #-}
112+
113+countdownEffectiveMVar :: Integer -> IO (Integer, Integer)
114+countdownEffectiveMVar n = E.runEff . ME.runState n $ programEffectiveMVar
115+
116+countdownEffectiveMVarDeep :: Integer -> IO (Integer, Integer)
117+countdownEffectiveMVarDeep n = E.runEff
118+ . runR . runR . runR . runR . runR . runR . runR . runR . runR . runR
119+ . ME.runState n
120+ . runR . runR . runR . runR . runR . runR . runR . runR . runR . runR
121+ $ programEffectiveMVar
122+ where
123+ runR = E.runReader ()
124+
93----------------------------------------
125----------------------------------------
94-- effective (dynamic)
126-- effective (dynamic)
95
127
@@ -103,11 +135,14 @@ programEffectiveDynamic = do
103 programEffectiveDynamic
135 programEffectiveDynamic
104{-# NOINLINE programEffectiveDynamic #-}
136{-# NOINLINE programEffectiveDynamic #-}
105
137
106−countdownEffectiveDynamic :: Integer -> IO (Integer, Integer)
138+countdownEffectiveDynPure :: Integer -> IO (Integer, Integer)
107−countdownEffectiveDynamic n = E.runEff . DE.runState n $ programEffectiveDynamic
139+countdownEffectiveDynPure n = E.runEff . DE.runState n $ programEffectiveDynamic
140+
141+countdownEffectiveDynMVar :: Integer -> IO (Integer, Integer)
142+countdownEffectiveDynMVar n = E.runEff . DE.runStateMVar n $ programEffectiveDynamic
108
143
109−countdownEffectiveDynamicDeep :: Integer -> IO (Integer, Integer)
144+countdownEffectiveDynPureDeep :: Integer -> IO (Integer, Integer)
110−countdownEffectiveDynamicDeep n = E.runEff
145+countdownEffectiveDynPureDeep n = E.runEff
111 . runR . runR . runR . runR . runR . runR . runR . runR . runR . runR
146 . runR . runR . runR . runR . runR . runR . runR . runR . runR . runR
112 . DE.runState n
147 . DE.runState n
113 . runR . runR . runR . runR . runR . runR . runR . runR . runR . runR
148 . runR . runR . runR . runR . runR . runR . runR . runR . runR . runR
@@ -115,6 +150,15 @@ countdownEffectiveDynamicDeep n = E.runEff
115 where
150 where
116 runR = E.runReader ()
151 runR = E.runReader ()
117
152
153+countdownEffectiveDynMVarDeep :: Integer -> IO (Integer, Integer)
154+countdownEffectiveDynMVarDeep n = E.runEff
155+ . runR . runR . runR . runR . runR . runR . runR . runR . runR . runR
156+ . DE.runStateMVar n
157+ . runR . runR . runR . runR . runR . runR . runR . runR . runR . runR
158+ $ programEffectiveDynamic
159+ where
160+ runR = E.runReader ()
161+
118----------------------------------------
162----------------------------------------
119-- fused-effects
163-- fused-effects
120
164
bench/Main.hs+8−4
@@ -10,8 +10,10 @@ main = defaultMain
10 [ bgroup "countdown"
10 [ bgroup "countdown"
11 [ bgroup "reference" $ mkCountdown nf countdownRef
11 [ bgroup "reference" $ mkCountdown nf countdownRef
12 , bgroup "shallow"
12 , bgroup "shallow"
13− [ bgroup "effective (S)" $ mkCountdown nfAppIO countdownEffectiveStatic
13+ [ bgroup "effective (SP)" $ mkCountdown nfAppIO countdownEffectiveStatic
14− , bgroup "effective (D)" $ mkCountdown nfAppIO countdownEffectiveDynamic
14+ , bgroup "effective (SM)" $ mkCountdown nfAppIO countdownEffectiveMVar
15+ , bgroup "effective (DP)" $ mkCountdown nfAppIO countdownEffectiveDynPure
16+ , bgroup "effective (DM)" $ mkCountdown nfAppIO countdownEffectiveDynMVar
15#ifdef VERSION_freer_simple
17#ifdef VERSION_freer_simple
16 , bgroup "freer-simple" $ mkCountdown nf countdownFreerSimple
18 , bgroup "freer-simple" $ mkCountdown nf countdownFreerSimple
17#endif
19#endif
@@ -27,8 +29,10 @@ main = defaultMain
27#endif
29#endif
28 ]
30 ]
29 , bgroup "deep"
31 , bgroup "deep"
30− [ bgroup "effective (S)" $ mkCountdown nfAppIO countdownEffectiveStaticDeep
32+ [ bgroup "effective (SP)" $ mkCountdown nfAppIO countdownEffectiveStaticDeep
31− , bgroup "effective (D)" $ mkCountdown nfAppIO countdownEffectiveDynamicDeep
33+ , bgroup "effective (SM)" $ mkCountdown nfAppIO countdownEffectiveMVarDeep
34+ , bgroup "effective (DP)" $ mkCountdown nfAppIO countdownEffectiveDynPureDeep
35+ , bgroup "effective (DM)" $ mkCountdown nfAppIO countdownEffectiveDynMVarDeep
32#ifdef VERSION_eff
36#ifdef VERSION_eff
33 , bgroup "eff" $ mkCountdown nf countdownEffDeep
37 , bgroup "eff" $ mkCountdown nf countdownEffDeep
34#endif
38#endif