on master help sign in
Describe performance characteristics of Env
e190279Andrzej Rybczak
src/Effectful/Internal/Env.hs+16−4
@@ -35,7 +35,19 @@ import Effectful.Internal.Has
35
35
36type role Env nominal
36type role Env nominal
37
37
38+-- | A mutable, strict (elements are kept in weak head normal form), extensible
38−-- | A mutable, extensible record indexed by effect data types.
39+-- record indexed by effect data types.
40+--
41+-- Offers pretty much perfect performance characteristics:
42+--
43+-- - Extending: /O(1)/ (amortized).
44+--
45+-- - Shrinking: /O(1)/.
46+--
47+-- - Indexing via '(:>)': /O(1)/ (amortized).
48+--
49+-- - Modification of a specific element: /O(1)/.
50+--
39newtype Env (es :: [Effect]) = Env (IORef EnvRef)
51newtype Env (es :: [Effect]) = Env (IORef EnvRef)
40
52
41data EnvRef = EnvRef Int (SmallMutableArray RealWorld Any)
53data EnvRef = EnvRef Int (SmallMutableArray RealWorld Any)
@@ -90,6 +102,9 @@ unsafeConsEnv e (Env ref) = do
90 e `seq` writeSmallArray es n (toAny e)
102 e `seq` writeSmallArray es n (toAny e)
91 writeIORef ref $! EnvRef (n + 1) es
103 writeIORef ref $! EnvRef (n + 1) es
92 pure $ Env ref
104 pure $ Env ref
105+ where
106+ doubleCapacity :: Int -> Int
107+ doubleCapacity n = max 1 n * 2
93{-# NOINLINE unsafeConsEnv #-}
108{-# NOINLINE unsafeConsEnv #-}
94
109
95-- | Shrink the environment by one data type (in place). Makes sure the size of
110-- | Shrink the environment by one data type (in place). Makes sure the size of
@@ -145,9 +160,6 @@ unsafeStateEnv f (Env ref) = do
145----------------------------------------
160----------------------------------------
146-- Internal helpers
161-- Internal helpers
147
162
148−doubleCapacity :: Int -> Int
149−doubleCapacity n = max 1 n * 2
150−
151toAny :: a -> Any
163toAny :: a -> Any
152toAny = unsafeCoerce
164toAny = unsafeCoerce
153
165