on 5cbcd5b help sign in
streamly/benchmark/StreamKOps.hs
205 lines 6.2 kB history raw
1-- |
2-- Module : StreamKOps
3-- Copyright : (c) 2018 Harendra Kumar
4--
5-- License : BSD3
6-- Maintainer : harendra.kumar@gmail.com
8{-# LANGUAGE FlexibleContexts #-}
10module StreamKOps where
12import Control.Monad (when)
13import Prelude
14 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
15 subtract, undefined, Maybe(..), not, mapM_, (>>=))
17import qualified Streamly.Streams.StreamK as S
18import qualified Streamly.Streams.Prelude as S
19import qualified Streamly.SVar as S
21value, maxValue :: Int
22value = 100000
23maxValue = value + 1000
25-------------------------------------------------------------------------------
26-- Benchmark ops
27-------------------------------------------------------------------------------
29{-# INLINE toNull #-}
30{-# INLINE uncons #-}
31{-# INLINE nullHeadTail #-}
32{-# INLINE scan #-}
33{-# INLINE map #-}
34{-# INLINE filterEven #-}
35{-# INLINE filterAllOut #-}
36{-# INLINE filterAllIn #-}
37{-# INLINE takeOne #-}
38{-# INLINE takeAll #-}
39{-# INLINE takeWhileTrue #-}
40{-# INLINE dropAll #-}
41{-# INLINE dropWhileTrue #-}
42{-# INLINE zip #-}
43{-# INLINE concat #-}
44{-# INLINE composeAllInFilters #-}
45{-# INLINE composeAllOutFilters #-}
46{-# INLINE composeMapAllInFilter #-}
47toNull, uncons, nullHeadTail, scan, map, filterEven, filterAllOut,
48 filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue, zip,
49 concat, composeAllInFilters, composeAllOutFilters,
50 composeMapAllInFilter
51 :: Monad m
52 => Stream m Int -> m ()
54{-# INLINE composeMapM #-}
55composeMapM :: S.MonadAsync m => Stream m Int -> m ()
57{-# INLINE toList #-}
58toList :: Monad m => Stream m Int -> m [Int]
59{-# INLINE foldl #-}
60foldl :: Monad m => Stream m Int -> m Int
61{-# INLINE last #-}
62last :: Monad m => Stream m Int -> m (Maybe Int)
64{-# INLINE mapM #-}
65mapM :: S.MonadAsync m => Stream m Int -> m ()
67-------------------------------------------------------------------------------
68-- Stream generation and elimination
69-------------------------------------------------------------------------------
71type Stream m a = S.Stream m a
73{-# INLINE sourceUnfoldr #-}
74sourceUnfoldr :: Int -> Stream m Int
75sourceUnfoldr n = S.unfoldr step n
76 where
77 step cnt =
78 if cnt > n + value
79 then Nothing
80 else Just (cnt, cnt + 1)
82{-# INLINE sourceUnfoldrM #-}
83sourceUnfoldrM :: S.MonadAsync m => Int -> Stream m Int
84sourceUnfoldrM n = S.unfoldrM step n
85 where
86 step cnt =
87 if cnt > n + value
88 then return Nothing
89 else return (Just (cnt, cnt + 1))
91{-
92{-# INLINE sourceFromEnum #-}
93sourceFromEnum :: Monad m => Int -> Stream m Int
94sourceFromEnum n = S.enumFromStepN n 1 value
95-}
97{-# INLINE sourceFromFoldable #-}
98sourceFromFoldable :: Int -> Stream m Int
99sourceFromFoldable n = S.fromFoldable [n..n+value]
101{-
102{-# INLINE sourceFromFoldableM #-}
103sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
104sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
105-}
107{-# INLINE sourceFoldMapWith #-}
108sourceFoldMapWith :: Int -> Stream m Int
109sourceFoldMapWith n = S.foldMapWith S.serial S.yield [n..n+value]
111{-# INLINE sourceFoldMapWithM #-}
112sourceFoldMapWithM :: Monad m => Int -> Stream m Int
113sourceFoldMapWithM n = S.foldMapWith S.serial (S.yieldM . return) [n..n+value]
115{-# INLINE source #-}
116source :: S.MonadAsync m => Int -> Stream m Int
117source = sourceUnfoldrM
119-------------------------------------------------------------------------------
120-- Elimination
121-------------------------------------------------------------------------------
123{-# INLINE runStream #-}
124runStream :: Monad m => Stream m a -> m ()
125runStream = S.runStream
127toNull = runStream
128uncons s = do
129 r <- S.uncons s
130 case r of
131 Nothing -> return ()
132 Just (_, t) -> uncons t
134{-# INLINE init #-}
135init :: (Monad m, S.IsStream t) => t m a -> m ()
136init s = do
137 t <- S.init s
138 mapM_ S.runStream t
140{-# INLINE tail #-}
141tail :: (Monad m, S.IsStream t) => t m a -> m ()
142tail s = S.tail s >>= mapM_ tail
144-- | If the stream is not null get its head and tail and then do the same to
145-- the tail.
146nullHeadTail s = do
147 r <- S.null s
148 when (not r) $ do
149 _ <- S.head s
150 S.tail s >>= mapM_ nullHeadTail
152toList = S.toList
153foldl = S.foldl' (+) 0
154last = S.last
156-------------------------------------------------------------------------------
157-- Transformation
158-------------------------------------------------------------------------------
160{-# INLINE transform #-}
161transform :: Monad m => Stream m a -> m ()
162transform = runStream
164scan = transform . S.scanl' (+) 0
165map = transform . fmap (+1)
166mapM = transform . S.mapM return
167filterEven = transform . S.filter even
168filterAllOut = transform . S.filter (> maxValue)
169filterAllIn = transform . S.filter (<= maxValue)
170takeOne = transform . S.take 1
171takeAll = transform . S.take maxValue
172takeWhileTrue = transform . S.takeWhile (<= maxValue)
173dropAll = transform . S.drop maxValue
174dropWhileTrue = transform . S.dropWhile (<= maxValue)
176-------------------------------------------------------------------------------
177-- Zipping and concat
178-------------------------------------------------------------------------------
180zip src = transform $ S.zipWith (,) src src
181concat _n = return ()
183-------------------------------------------------------------------------------
184-- Composition
185-------------------------------------------------------------------------------
187{-# INLINE compose #-}
188compose :: Monad m => (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
189compose f = transform . f . f . f . f
191composeMapM = compose (S.mapM return)
192composeAllInFilters = compose (S.filter (<= maxValue))
193composeAllOutFilters = compose (S.filter (> maxValue))
194composeMapAllInFilter = compose (S.filter (<= maxValue) . fmap (subtract 1))
196{-# INLINABLE composeScaling #-}
197composeScaling :: Monad m => Int -> Stream m Int -> m ()
198composeScaling m =
199 case m of
200 1 -> transform . f
201 2 -> transform . f . f
202 3 -> transform . f . f . f
203 4 -> transform . f . f . f . f
204 _ -> undefined
205 where f = S.filter (<= maxValue)