@@ -12,15 +12,28 @@ module Main (main) where
12import Control.DeepSeq (NFData(..))
12import Control.DeepSeq (NFData(..))
13import Data.Monoid (Last(..), Sum(..))
13import Data.Monoid (Last(..), Sum(..))
14import System.Random (randomRIO)
14import System.Random (randomRIO)
15+import Prelude (IO, Int, Double, String, (>), (<$>), (+), ($), even,
16+ (<=), Monad(..), (==), Maybe(..), (.), fromIntegral,
17+ compare, (>=), concat, seq, mod, fst, snd, const, Bool, Ord(..),
18+ div, Num(..), odd, Either(..))
16−import qualified Streamly.Data.Array.Storable.Foreign as A
20+import Data.Map.Strict (Map)
22+import Streamly.Prelude (SerialT)
23+import Streamly.Internal.Data.Fold (Fold(..))
25+import qualified Data.Map.Strict as Map
17−import qualified Streamly.Data.Fold as FL
27+import qualified Streamly.Prelude as S
18−import qualified Streamly.Internal.Data.Array.Storable.Foreign as IA
28+import qualified Streamly.Internal.Data.Fold as FL
19−import qualified Streamly.Internal.Data.Fold as IFL
29+import qualified Streamly.Internal.Data.Fold.Types as FL
20import qualified Streamly.Internal.Data.Pipe as Pipe
30import qualified Streamly.Internal.Data.Pipe as Pipe
21import qualified Streamly.Internal.Data.Sink as Sink
32import qualified Streamly.Internal.Data.Sink as Sink
34+import qualified Streamly.Data.Array.Storable.Foreign as A
35+import qualified Streamly.Internal.Data.Array.Storable.Foreign as IA
22import qualified Streamly.Internal.Data.Stream.IsStream as IP
36import qualified Streamly.Internal.Data.Stream.IsStream as IP
23−import qualified Streamly.Prelude as S
25import Gauge
38import Gauge
26import Streamly.Benchmark.Common
39import Streamly.Benchmark.Common
@@ -49,7 +62,110 @@ benchIOSink
49benchIOSink value name f = bench name $ nfIO $ randomRIO (1,1) >>= f . source value
62benchIOSink value name f = bench name $ nfIO $ randomRIO (1,1) >>= f . source value
51-------------------------------------------------------------------------------
64-------------------------------------------------------------------------------
52−-- Stream folds
65+-- Folds
66+-------------------------------------------------------------------------------
69+any :: (Monad m, Ord a) => a -> SerialT m a -> m Bool
70+any value = IP.fold (FL.any (> value))
73+all :: (Monad m, Ord a) => a -> SerialT m a -> m Bool
74+all value = IP.fold (FL.all (<= value))
77+take :: Monad m => Int -> SerialT m a -> m ()
78+take value = IP.fold (FL.ltake value FL.drain)
80+{-# INLINE takeSepBy #-}
81+takeSepBy :: Monad m => Int -> SerialT m Int -> m ()
82+takeSepBy value = IP.fold (FL.takeSepBy (<= value) FL.drain)
85+many :: Monad m => SerialT m Int -> m Int
86+many = IP.fold (FL.many FL.length FL.sum)
88+{-# INLINE splitAllAny #-}
89+splitAllAny :: Monad m => Int -> SerialT m Int -> m (Bool, Bool)
91+ IP.fold (FL.splitWith (,) (FL.all (<= (value `div` 2))) (FL.any (> value)))
93+{-# INLINE teeAllAny #-}
94+teeAllAny :: (Monad m, Ord a) => a -> SerialT m a -> m (Bool, Bool)
96+ IP.fold (FL.teeWith (,) (FL.all (<= value)) (FL.any (> value)))
98+{-# INLINE teeSumLength #-}
99+teeSumLength :: Monad m => SerialT m Int -> m (Int, Int)
100+teeSumLength = IP.fold (FL.teeWith (,) FL.sum FL.length)
103+{-# INLINE applicativeAllAny #-}
104+applicativeAllAny :: (Monad m, Ord a) => a -> SerialT m a -> m (Bool, Bool)
105+applicativeAllAny value =
106+ IP.fold ((,) <$> FL.all (<= value) <*> (FL.any (> value)))
108+{-# INLINE applicativeSumLength #-}
109+applicativeSumLength :: Monad m => SerialT m Int -> m (Int, Int)
110+applicativeSumLength = IP.fold ((,) <$> FL.sum <*> FL.length)
113+{-# INLINE distribute_ #-}
114+distribute_ :: Monad m => SerialT m Int -> m ()
116+ IP.fold (FL.distribute_ [const () <$> FL.sum, const () <$> FL.length])
118+{-# INLINE distribute #-}
119+distribute :: Monad m => SerialT m Int -> m [Int]
120+distribute = IP.fold (FL.distribute [FL.sum, FL.length])
122+{-# INLINE partition #-}
123+partition :: Monad m => SerialT m Int -> m (Int, Int)
129+ in IP.fold $ FL.lmap f (FL.partition FL.sum FL.length)
132+unzip :: Monad m => SerialT m Int -> m (Int, Int)
133+unzip = IP.fold $ FL.lmap (\a -> (a, a)) (FL.unzip FL.sum FL.length)
135+{-# INLINE demuxWith #-}
139+ -> Map k (Fold m a' b)
142+demuxWith f mp = S.fold (FL.demuxWith f mp)
144+{-# INLINE demuxWith_ #-}
148+ -> Map k (Fold m a' b)
151+demuxWith_ f mp = S.fold (FL.demuxWith_ f mp)
153+{-# INLINE demuxWithDefault_ #-}
155+ (Monad m, Ord k, Num b)
157+ -> Map k (Fold m b b)
160+demuxWithDefault_ f mp = S.fold (FL.demuxWithDefault_ f mp (FL.lmap snd FL.sum))
162+{-# INLINE classifyWith #-}
164+ (Monad m, Ord k, Num a) => (a -> k) -> SerialT m a -> m (Map k a)
165+classifyWith f = S.fold (FL.classifyWith f FL.sum)
167+-------------------------------------------------------------------------------
53-------------------------------------------------------------------------------
169-------------------------------------------------------------------------------
55moduleName :: String
171moduleName :: String
@@ -61,15 +177,15 @@ o_1_space_serial_elimination value =
61 [ bgroup "elimination"
177 [ bgroup "elimination"
62 [ benchIOSink value "drain" (S.fold FL.drain)
178 [ benchIOSink value "drain" (S.fold FL.drain)
63 , benchIOSink value "drainBy" (S.fold (FL.drainBy return))
179 , benchIOSink value "drainBy" (S.fold (FL.drainBy return))
64− , benchIOSink value "drainN" (S.fold (IFL.drainN value))
180+ , benchIOSink value "drainN" (S.fold (FL.drainN value))
65 , benchIOSink
181 , benchIOSink
67− "drainWhileTrue"
183+ "drainSepByTrue"
68− (S.fold (IFL.drainWhile $ (<=) (value + 1)))
184+ (S.fold (FL.drainSepBy $ (<=) (value + 1)))
69 , benchIOSink
185 , benchIOSink
71− "drainWhileFalse"
187+ "drainSepByFalse"
72− (S.fold (IFL.drainWhile $ (>=) (value + 1)))
188+ (S.fold (FL.drainSepBy $ (>=) (value + 1)))
73 , benchIOSink value "sink" (S.fold $ Sink.toFold Sink.drain)
189 , benchIOSink value "sink" (S.fold $ Sink.toFold Sink.drain)
74 , benchIOSink value "last" (S.fold FL.last)
190 , benchIOSink value "last" (S.fold FL.last)
75 , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
191 , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
@@ -121,7 +237,7 @@ o_1_space_serial_elimination value =
121 , benchIOSink
237 , benchIOSink
124− (S.fold (IFL.lmap (\a -> (a, a)) (FL.lookup (value + 1))))
240+ (S.fold (FL.lmap (\a -> (a, a)) (FL.lookup (value + 1))))
125 , benchIOSink
241 , benchIOSink
127 "findIndex"
243 "findIndex"
@@ -133,8 +249,10 @@ o_1_space_serial_elimination value =
133 , benchIOSink value "null" (S.fold FL.null)
249 , benchIOSink value "null" (S.fold FL.null)
134 , benchIOSink value "elem" (S.fold (FL.elem (value + 1)))
250 , benchIOSink value "elem" (S.fold (FL.elem (value + 1)))
135 , benchIOSink value "notElem" (S.fold (FL.notElem (value + 1)))
251 , benchIOSink value "notElem" (S.fold (FL.notElem (value + 1)))
136− , benchIOSink value "all" (S.fold (FL.all (<= (value + 1))))
252+ , benchIOSink value "all" $ all value
253+ , benchIOSink value "any" $ any value
137− , benchIOSink value "any" (S.fold (FL.any (> (value + 1))))
254+ , benchIOSink value "take" $ take value
255+ , benchIOSink value "takeSepBy" $ takeSepBy value
138 , benchIOSink
256 , benchIOSink
@@ -152,9 +270,9 @@ o_1_space_serial_transformation :: Int -> [Benchmark]
152o_1_space_serial_transformation value =
270o_1_space_serial_transformation value =
153 [ bgroup "serially"
271 [ bgroup "serially"
154 [ bgroup "transformation"
272 [ bgroup "transformation"
155− [ benchIOSink value "lmap" (S.fold (IFL.lmap (+ 1) FL.drain))
273+ [ benchIOSink value "lmap" (S.fold (FL.lmap (+ 1) FL.drain))
156 , let f x = if even x then Just x else Nothing
274 , let f x = if even x then Just x else Nothing
157− fld = IFL.mapMaybe f FL.drain
275+ fld = FL.mapMaybe f FL.drain
158 in benchIOSink value "mapMaybe" (S.fold fld)
276 in benchIOSink value "mapMaybe" (S.fold fld)
159 , benchIOSink
277 , benchIOSink
@@ -165,7 +283,7 @@ o_1_space_serial_transformation value =
166 "pipe-mapM"
284 "pipe-mapM"
168− (IFL.transform
286+ (FL.transform
169 (Pipe.mapM (\x -> return $ x + 1))
287 (Pipe.mapM (\x -> return $ x + 1))
170 FL.drain))
288 FL.drain))
@@ -174,40 +292,39 @@ o_1_space_serial_transformation value =
175o_1_space_serial_composition :: Int -> [Benchmark]
293o_1_space_serial_composition :: Int -> [Benchmark]
176o_1_space_serial_composition value =
294o_1_space_serial_composition value =
177− [ bgroup "serially"
296+ "serially"
178− [ bgroup "composition" -- Applicative
298+ "composition"
179− [ benchIOSink
300+ [ benchIOSink value "tee (all, any)" $ teeAllAny value
180− value
301+ , benchIOSink value "tee (sum, length)" $ teeSumLength
181− "all,any"
302+ -- , benchIOSink value "applicative (all, any)"
182− (S.fold
303+ -- $ applicativeAllAny value
183− ((,) <$> FL.all (<= (value + 1)) <*>
304+ -- , benchIOSink value "applicative (sum, length)"
184− FL.any (> (value + 1))))
305+ -- $ applicativeSumLength
185− , benchIOSink
306+ , benchIOSink value "distribute_ [sum, length]" $ distribute_
186− value
307+ , benchIOSink value "distribute [sum, length]" $ distribute
188− (S.fold ((,) <$> FL.sum <*> FL.length))
189− , benchIOSink
308+ , benchIOSink value "partition (sum, length)" $ partition
190− value
309+ , benchIOSink value "unzip (sum, length)" $ unzip
191− "tee sum length"
310+ , benchIOSink value "demuxWith [sum, length]" $ demuxWith fn mp
192− (S.fold (FL.tee FL.sum FL.length))
311+ , benchIOSink value "demuxWith_ [sum, length]"
193− , benchIOSink
312+ $ demuxWith_ fn mp
194− value
313+ , benchIOSink value "demuxWithDefault_ [sum, length] sum"
195− "distribute sum length"
314+ $ demuxWithDefault_ fn mp
196− (S.fold (FL.distribute [FL.sum, FL.length]))
315+ , benchIOSink value "classifyWith sum" $ classifyWith (fst . fn)
199− "partition sum length"
201− (\a -> if odd a then Left a else Right a)
202− (FL.partition FL.sum FL.length)))
203− , benchIOSink
316+ , benchIOSink value "many length sum" many
204− value
317+ , benchIOSink value "split (all, any)" $ splitAllAny value
206− (S.fold (IFL.lmap (\a -> (a, a)) (FL.unzip FL.sum FL.length)))
324+ fn x = (x `mod` 3, x)
326+ mp = Map.fromList [(0, FL.sum), (1, FL.length)]
211o_n_heap_serial :: Int -> [Benchmark]
328o_n_heap_serial :: Int -> [Benchmark]
212o_n_heap_serial value =
329o_n_heap_serial value =
213 [ bgroup "serially"
330 [ bgroup "serially"
@@ -217,7 +334,7 @@ o_n_heap_serial value =
217 [ benchIOSink value "toStream" (S.fold IP.toStream)
334 [ benchIOSink value "toStream" (S.fold IP.toStream)
218 , benchIOSink value "toStreamRev" (S.fold IP.toStreamRev)
335 , benchIOSink value "toStreamRev" (S.fold IP.toStreamRev)
219 , benchIOSink value "toList" (S.fold FL.toList)
336 , benchIOSink value "toList" (S.fold FL.toList)
220− , benchIOSink value "toListRevF" (S.fold IFL.toListRevF)
337+ , benchIOSink value "toListRevF" (S.fold FL.toListRevF)
221 -- Converting the stream to an array
338 -- Converting the stream to an array
222 , benchIOSink value "lastN.Max" (S.fold (IA.lastN (value + 1)))
339 , benchIOSink value "lastN.Max" (S.fold (IA.lastN (value + 1)))
223 , benchIOSink value "writeN" (S.fold (A.writeN value))
340 , benchIOSink value "writeN" (S.fold (A.writeN value))