@@ -11,10 +11,11 @@ module Main (main) where
12import Control.DeepSeq (NFData(..))
12import Control.DeepSeq (NFData(..))
13import System.Random (randomRIO)
13import System.Random (randomRIO)
14+import Streamly.Internal.Data.Unfold (Unfold)
15import qualified Prelude
16import qualified Prelude
17+import qualified Streamly.Internal.Data.Fold as FL
16import qualified Streamly.Internal.Data.Unfold as UF
18import qualified Streamly.Internal.Data.Unfold as UF
17−import qualified Streamly.Internal.Data.Stream.IsStream as S
19import Streamly.Benchmark.Common
20import Streamly.Benchmark.Common
20import Streamly.Benchmark.Data.NestedUnfoldOps
21import Streamly.Benchmark.Data.NestedUnfoldOps
@@ -25,6 +26,52 @@ import Prelude hiding (concat, take)
25benchIO :: (NFData b) => String -> (Int -> IO b) -> Benchmark
26benchIO :: (NFData b) => String -> (Int -> IO b) -> Benchmark
26benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
27benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
29+-------------------------------------------------------------------------------
31+-------------------------------------------------------------------------------
33+{-# INLINE drainUnfold #-}
34+drainUnfold :: Monad m => Unfold m a b -> a -> m ()
35+drainUnfold unf seed = UF.fold unf FL.drain seed
37+{-# INLINE drainGeneration #-}
38+drainGeneration :: Monad m => Unfold m a b -> a -> m ()
39+drainGeneration = drainUnfold
41+{-# INLINE drainTransformation #-}
42+drainTransformation ::
43+ Monad m => Unfold m a b -> (Unfold m a b -> Unfold m c d) -> c -> m ()
44+drainTransformation unf f seed = drainUnfold (f unf) seed
46+{-# INLINE drainTransformationDefault #-}
47+drainTransformationDefault ::
48+ Monad m => Int -> (Unfold m Int Int -> Unfold m c d) -> c -> m ()
49+drainTransformationDefault size =
50+ drainTransformation (UF.take size UF.enumerateFromIntegral)
52+{-# INLINE drainProduct #-}
57+ -> (Unfold m a b -> Unfold m c d -> Unfold m e f)
60+drainProduct unf1 unf2 f seed = drainUnfold (f unf1 unf2) seed
62+{-# INLINE drainProductDefault #-}
63+drainProductDefault ::
66+ -> (Unfold m Int Int -> Unfold m Int Int -> Unfold m e f)
69+drainProductDefault size = drainProduct src src
73+ src = UF.take size UF.enumerateFromIntegral
28-------------------------------------------------------------------------------
75-------------------------------------------------------------------------------
29-- Stream generation
76-- Stream generation
30-------------------------------------------------------------------------------
77-------------------------------------------------------------------------------
@@ -32,26 +79,25 @@ benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
32{-# INLINE fromListM #-}
79{-# INLINE fromListM #-}
33fromListM :: Monad m => Int -> Int -> m ()
80fromListM :: Monad m => Int -> Int -> m ()
34fromListM size start =
81fromListM size start =
36− $ S.unfold UF.fromListM (Prelude.map return [start .. start + size])
82+ drainGeneration UF.fromListM (Prelude.map return [start .. start + size])
38{-# INLINE replicateM #-}
84{-# INLINE replicateM #-}
39replicateM :: Monad m => Int -> Int -> m ()
85replicateM :: Monad m => Int -> Int -> m ()
40−replicateM size start = S.drain $ S.unfold (UF.replicateM size) (return start)
86+replicateM size start = drainGeneration (UF.replicateM size) (return start)
42{-# INLINE repeatM #-}
88{-# INLINE repeatM #-}
43repeatM :: Monad m => Int -> Int -> m ()
89repeatM :: Monad m => Int -> Int -> m ()
44−repeatM size start = S.drain $ S.take size $ S.unfold UF.repeatM (return start)
90+repeatM size start = drainGeneration (UF.take size UF.repeatM) (return start)
46{-# INLINE enumerateFromStepIntegral #-}
92{-# INLINE enumerateFromStepIntegral #-}
47enumerateFromStepIntegral :: Monad m => Int -> Int -> m ()
93enumerateFromStepIntegral :: Monad m => Int -> Int -> m ()
48−enumerateFromStepIntegral size start = S.drain $
94+enumerateFromStepIntegral size start =
49− S.take size $ S.unfold UF.enumerateFromStepIntegral (start, 1)
95+ drainGeneration (UF.take size UF.enumerateFromStepIntegral) (start, 1)
51{-# INLINE enumerateFromToIntegral #-}
97{-# INLINE enumerateFromToIntegral #-}
52enumerateFromToIntegral :: Monad m => Int -> Int -> m ()
98enumerateFromToIntegral :: Monad m => Int -> Int -> m ()
53enumerateFromToIntegral size start =
99enumerateFromToIntegral size start =
54− S.drain $ S.unfold (UF.enumerateFromToIntegral (size + start)) start
100+ drainGeneration (UF.enumerateFromToIntegral (size + start)) start
56-------------------------------------------------------------------------------
102-------------------------------------------------------------------------------
57-- Stream transformation
103-- Stream transformation
@@ -59,55 +105,41 @@ enumerateFromToIntegral size start =
60{-# INLINE take #-}
106{-# INLINE take #-}
61take :: Monad m => Int -> Int -> m ()
107take :: Monad m => Int -> Int -> m ()
62−take size start =
108+take size start = drainTransformationDefault size (UF.take size) start
65− (UF.take size (UF.enumerateFromToIntegral (size + start)))
68{-# INLINE takeWhileM #-}
110{-# INLINE takeWhileM #-}
69takeWhileM :: Monad m => Int -> Int -> m ()
111takeWhileM :: Monad m => Int -> Int -> m ()
70takeWhileM size start =
112takeWhileM size start =
71− S.drain
113+ drainTransformationDefault
74− (\b -> return (b <= size + start))
115+ (UF.takeWhileM (\b -> return (b <= size + start)))
75− (UF.enumerateFromToIntegral (size + start)))
78{-# INLINE _dropOne #-}
118{-# INLINE _dropOne #-}
79_dropOne :: Monad m => Int -> Int -> m ()
119_dropOne :: Monad m => Int -> Int -> m ()
80_dropOne size start =
120_dropOne size start =
81− S.drain
121+ drainTransformationDefault size (UF.drop 1) start
82− $ S.unfold (UF.drop 1 (UF.enumerateFromToIntegral (size + start))) start
84{-# INLINE dropAll #-}
123{-# INLINE dropAll #-}
85dropAll :: Monad m => Int -> Int -> m ()
124dropAll :: Monad m => Int -> Int -> m ()
86dropAll size start =
125dropAll size start =
87− S.drain
126+ drainTransformationDefault size (UF.drop (size + 1)) start
89− (UF.drop (size + 1) (UF.enumerateFromToIntegral (size + start)))
92{-# INLINE dropWhileMTrue #-}
128{-# INLINE dropWhileMTrue #-}
93dropWhileMTrue :: Monad m => Int -> Int -> m ()
129dropWhileMTrue :: Monad m => Int -> Int -> m ()
94dropWhileMTrue size start =
130dropWhileMTrue size start =
95− S.drain
131+ drainTransformationDefault
97− (UF.dropWhileM
133+ (UF.dropWhileM (\_ -> return True))
99− (UF.enumerateFromToIntegral (size + start)))
102{-# INLINE dropWhileMFalse #-}
136{-# INLINE dropWhileMFalse #-}
103dropWhileMFalse :: Monad m => Int -> Int -> m ()
137dropWhileMFalse :: Monad m => Int -> Int -> m ()
104dropWhileMFalse size start =
138dropWhileMFalse size start =
105− S.drain
139+ drainTransformationDefault
107− (UF.dropWhileM
141+ (UF.dropWhileM (\_ -> return False))
108− (\_ -> return False)
109− (UF.enumerateFromToIntegral (size + start)))
112-------------------------------------------------------------------------------
144-------------------------------------------------------------------------------
113-- Stream combination
145-- Stream combination
@@ -116,13 +148,10 @@ dropWhileMFalse size start =
116{-# INLINE zipWithM #-}
148{-# INLINE zipWithM #-}
117zipWithM :: Monad m => Int -> Int -> m ()
149zipWithM :: Monad m => Int -> Int -> m ()
118zipWithM size start =
150zipWithM size start =
119− S.drain
151+ drainProductDefault
121− (UF.zipWithM
153+ (UF.zipWithM (\a b -> return $ a + b))
122− (\a b -> return $ a + b)
123− (UF.enumerateFromToIntegral (size + start))
124− (UF.enumerateFromToIntegral (size + start + 1)))
125− (start, start + 1)
154+ (start, start + 1)
127-------------------------------------------------------------------------------
156-------------------------------------------------------------------------------
128-- Benchmarks
157-- Benchmarks