@@ -10,38 +10,165 @@
1010module Main (main) where
1111
1212import Control.DeepSeq (NFData(..))
13−
1413import System.Random (randomRIO)
1514
16−import Gauge
17−
18−import Prelude hiding (concat)
19−
2015import qualified Prelude
16+import qualified Streamly.Internal.Data.Unfold as UF
17+import qualified Streamly.Internal.Data.Stream.IsStream as S
2118
2219import Streamly.Benchmark.Common
2320import Streamly.Benchmark.Data.NestedUnfoldOps
21+import Gauge
22+import Prelude hiding (concat, take)
2423
2524{-# INLINE benchIO #-}
2625benchIO :: (NFData b) => String -> (Int -> IO b) -> Benchmark
2726benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
2827
2928-------------------------------------------------------------------------------
30−-- Outer product
29+-- Stream generation
30+-------------------------------------------------------------------------------
31+
32+{-# INLINE fromListM #-}
33+fromListM :: Monad m => Int -> Int -> m ()
34+fromListM value n =
35+ S.drain $ S.unfold UF.fromListM (Prelude.map return [n .. n + value])
36+
37+{-# INLINE replicateM #-}
38+replicateM :: Monad m => Int -> Int -> m ()
39+replicateM value n = S.drain $ S.unfold (UF.replicateM value) n
40+
41+{-# INLINE repeatM #-}
42+repeatM :: Monad m => Int -> Int -> m ()
43+repeatM value n = S.drain $ S.take value $ S.unfold UF.repeatM n
44+
45+{-# INLINE enumerateFromStepIntegral #-}
46+enumerateFromStepIntegral :: Monad m => Int -> Int -> m ()
47+enumerateFromStepIntegral value n = S.drain $
48+ S.take value $ S.unfold UF.enumerateFromStepIntegral (n, 1)
49+
50+{-# INLINE enumerateFromToIntegral #-}
51+enumerateFromToIntegral :: Monad m => Int -> Int -> m ()
52+enumerateFromToIntegral value n =
53+ S.drain $ S.unfold (UF.enumerateFromToIntegral (value + n)) n
54+
55+-------------------------------------------------------------------------------
56+-- Stream transformation
57+-------------------------------------------------------------------------------
58+
59+-- XXX Investigate
60+{-# INLINE take #-}
61+take :: Monad m => Int -> Int -> m ()
62+take value n =
63+ S.drain
64+ $ S.unfold (UF.take value (UF.enumerateFromToIntegral (value + n))) n
65+
66+{-# INLINE takeWhileM #-}
67+takeWhileM :: Monad m => Int -> Int -> m ()
68+takeWhileM value n =
69+ S.drain
70+ $ S.unfold
71+ (UF.takeWhileM
72+ (\b -> return (b <= value + n))
73+ (UF.enumerateFromToIntegral (value + n)))
74+ n
75+
76+{-# INLINE dropOne #-}
77+dropOne :: Monad m => Int -> Int -> m ()
78+dropOne value n =
79+ S.drain $ S.unfold (UF.drop 1 (UF.enumerateFromToIntegral (value + n))) n
80+
81+{-# INLINE dropAll #-}
82+dropAll :: Monad m => Int -> Int -> m ()
83+dropAll value n =
84+ S.drain
85+ $ S.unfold
86+ (UF.drop (value + 1) (UF.enumerateFromToIntegral (value + n)))
87+ n
88+
89+{-# INLINE dropWhileMTrue #-}
90+dropWhileMTrue :: Monad m => Int -> Int -> m ()
91+dropWhileMTrue value n =
92+ S.drain
93+ $ S.unfold
94+ (UF.dropWhileM
95+ (\_ -> return True)
96+ (UF.enumerateFromToIntegral (value + n)))
97+ n
98+
99+{-# INLINE dropWhileMFalse #-}
100+dropWhileMFalse :: Monad m => Int -> Int -> m ()
101+dropWhileMFalse value n =
102+ S.drain
103+ $ S.unfold
104+ (UF.dropWhileM
105+ (\_ -> return False)
106+ (UF.enumerateFromToIntegral (value + n)))
107+ n
108+
109+-------------------------------------------------------------------------------
110+-- Stream combination
111+-------------------------------------------------------------------------------
112+
113+{-# INLINE zipWithM #-}
114+zipWithM :: Monad m => Int -> Int -> m ()
115+zipWithM value n =
116+ S.drain
117+ $ S.unfold
118+ (UF.zipWithM
119+ (\a b -> return $ a + b)
120+ (UF.enumerateFromToIntegral (value + n))
121+ (UF.enumerateFromToIntegral (value + n + 1)))
122+ (n, n + 1)
123+
124+-------------------------------------------------------------------------------
125+-- Benchmarks
31126-------------------------------------------------------------------------------
32127
33128moduleName :: String
34129moduleName = "Data.Unfold"
35130
36−o_1_space_serial :: Int -> [Benchmark]
37−o_1_space_serial value =
131+o_1_space_serial_generation :: Int -> [Benchmark]
132+o_1_space_serial_generation value =
133+ [ bgroup "generation"
134+ [ benchIO "fromListM" $ fromListM value
135+ , benchIO "replicateM" $ replicateM value
136+ , benchIO "repeatM" $ repeatM value
137+ , benchIO "enumerateFromStepIntegral" $ enumerateFromStepIntegral value
138+ , benchIO "enumerateFromToIntegral" $ enumerateFromToIntegral value
139+ ]
140+ ]
141+
142+o_1_space_serial_transformation :: Int -> [Benchmark]
143+o_1_space_serial_transformation value =
144+ [ bgroup "transformation"
145+ [ benchIO "take" $ take value
146+ , benchIO "takeWhileM" $ takeWhileM value
147+ , benchIO "filterAllOut" $ filterAllOut value
148+ , benchIO "filterAllIn" $ filterAllIn value
149+ , benchIO "filterSome" $ filterSome value
150+ , benchIO "dropOne" $ dropOne value
151+ , benchIO "dropAll" $ dropAll value
152+ , benchIO "dropWhileMTrue" $ dropWhileMTrue value
153+ , benchIO "dropWhileMFalse" $ dropWhileMFalse value
154+ ]
155+ ]
156+
157+
158+o_1_space_serial_combination :: Int -> [Benchmark]
159+o_1_space_serial_combination value =
160+ [ bgroup "combination"
161+ [ benchIO "zipWithM" $ zipWithM value
162+ ]
163+ ]
164+
165+
166+o_1_space_serial_outerProduct :: Int -> [Benchmark]
167+o_1_space_serial_outerProduct value =
38168 [ bgroup "outer-product"
39169 [ benchIO "toNull" $ toNull value
40170 , benchIO "toNull3" $ toNull3 value
41171 , benchIO "concat" $ concat value
42− , benchIO "filterAllOut" $ filterAllOut value
43− , benchIO "filterAllIn" $ filterAllIn value
44− , benchIO "filterSome" $ filterSome value
45172 , benchIO "breakAfterSome" $ breakAfterSome value
46173 ]
47174 ]
@@ -66,8 +193,13 @@ main = do
66193 where
67194
68195 allBenchmarks value =
69− [ bgroup (o_1_space_prefix moduleName) $ Prelude.concat
70− [o_1_space_serial value]
71− , bgroup (o_n_space_prefix moduleName) $ Prelude.concat
72− [o_n_space_serial value]
196+ [ bgroup (o_1_space_prefix moduleName)
197+ $ Prelude.concat
198+ [ o_1_space_serial_generation value
199+ , o_1_space_serial_transformation value
200+ , o_1_space_serial_combination value
201+ , o_1_space_serial_outerProduct value
202+ ]
203+ , bgroup (o_n_space_prefix moduleName)
204+ $ Prelude.concat [o_n_space_serial value]
73205 ]