on ec08681 help sign in
streamly/benchmark/LinearOps.hs
275 lines 8.6 kB history raw
1-- |
2-- Module : BenchmarkOps
3-- Copyright : (c) 2018 Harendra Kumar
4--
5-- License : MIT
6-- Maintainer : harendra.kumar@gmail.com
8{-# LANGUAGE FlexibleContexts #-}
10module LinearOps where
12import Data.Maybe (fromJust)
13import Prelude
14 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
15 subtract, undefined, Maybe(..), odd, Bool, not)
17import qualified Streamly as S
18import qualified Streamly.Prelude as S
20value, maxValue :: Int
21value = 100000
22maxValue = value + 1000
24-------------------------------------------------------------------------------
25-- Benchmark ops
26-------------------------------------------------------------------------------
28{-# INLINE uncons #-}
29{-# INLINE nullHeadTail #-}
30{-# INLINE scan #-}
31{-# INLINE mapM_ #-}
32{-# INLINE map #-}
33{-# INLINE fmap #-}
34{-# INLINE mapMaybe #-}
35{-# INLINE filterEven #-}
36{-# INLINE filterAllOut #-}
37{-# INLINE filterAllIn #-}
38{-# INLINE takeOne #-}
39{-# INLINE takeAll #-}
40{-# INLINE takeWhileTrue #-}
41{-# INLINE takeWhileMTrue #-}
42{-# INLINE dropAll #-}
43{-# INLINE dropWhileTrue #-}
44{-# INLINE dropWhileMTrue #-}
45{-# INLINE zip #-}
46{-# INLINE zipM #-}
47{-# INLINE concat #-}
48{-# INLINE composeAllInFilters #-}
49{-# INLINE composeAllOutFilters #-}
50{-# INLINE composeMapAllInFilter #-}
51uncons, nullHeadTail, scan, mapM_, map, fmap, mapMaybe, filterEven, filterAllOut,
52 filterAllIn, takeOne, takeAll, takeWhileTrue, takeWhileMTrue, dropAll,
53 dropWhileTrue, dropWhileMTrue, zip, zipM,
54 concat, composeAllInFilters, composeAllOutFilters,
55 composeMapAllInFilter
56 :: Monad m
57 => Stream m Int -> m ()
59{-# INLINE composeMapM #-}
60{-# INLINE zipAsync #-}
61{-# INLINE zipAsyncM #-}
62{-# INLINE mapMaybeM #-}
63composeMapM, zipAsync, zipAsyncM, mapMaybeM :: S.MonadAsync m => Stream m Int -> m ()
65{-# INLINE toList #-}
66{-# INLINE foldr #-}
67{-# INLINE foldrM #-}
68toList, foldr, foldrM :: Monad m => Stream m Int -> m [Int]
70{-# INLINE last #-}
71{-# INLINE maximum #-}
72{-# INLINE minimum #-}
73last, minimum, maximum :: Monad m => Stream m Int -> m (Maybe Int)
75{-# INLINE foldl #-}
76{-# INLINE length #-}
77{-# INLINE sum #-}
78{-# INLINE product #-}
79foldl, length, sum, product :: Monad m => Stream m Int -> m Int
81{-# INLINE all #-}
82{-# INLINE any #-}
83{-# INLINE elem #-}
84{-# INLINE notElem #-}
85elem, notElem, all, any :: Monad m => Stream m Int -> m Bool
87{-# INLINE toNull #-}
88toNull :: Monad m => (t m Int -> S.SerialT m Int) -> t m Int -> m ()
90{-# INLINE mapM #-}
91mapM :: (S.IsStream t, S.MonadAsync m)
92 => (t m Int -> S.SerialT m Int) -> t m Int -> m ()
94{-# INLINE sequence #-}
95sequence :: (S.IsStream t, S.MonadAsync m)
96 => (t m Int -> S.SerialT m Int) -> t m (m Int) -> m ()
98-------------------------------------------------------------------------------
99-- Stream generation and elimination
100-------------------------------------------------------------------------------
102type Stream m a = S.SerialT m a
104{-# INLINE source #-}
105source :: (S.MonadAsync m, S.IsStream t) => Int -> t m Int
106source n = S.serially $ sourceUnfoldrM n
107-- source n = S.serially $ sourceFromList n
109{-# INLINE sourceFromList #-}
110sourceFromList :: (Monad m, S.IsStream t) => Int -> t m Int
111sourceFromList n = S.fromList [n..n+value]
113{-# INLINE sourceFromListM #-}
114sourceFromListM :: (S.MonadAsync m, S.IsStream t) => Int -> t m Int
115sourceFromListM n = S.fromListM (Prelude.fmap return [n..n+value])
117{-# INLINE sourceFromFoldable #-}
118sourceFromFoldable :: S.IsStream t => Int -> t m Int
119sourceFromFoldable n = S.fromFoldable [n..n+value]
121{-# INLINE sourceFromFoldableM #-}
122sourceFromFoldableM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
123sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
125{-# INLINE sourceFoldMapWith #-}
126sourceFoldMapWith :: (S.IsStream t, S.Semigroup (t m Int))
127 => Int -> t m Int
128sourceFoldMapWith n = S.foldMapWith (S.<>) S.yield [n..n+value]
130{-# INLINE sourceFoldMapWithM #-}
131sourceFoldMapWithM :: (S.IsStream t, Monad m, S.Semigroup (t m Int))
132 => Int -> t m Int
133sourceFoldMapWithM n = S.foldMapWith (S.<>) (S.yieldM . return) [n..n+value]
135{-# INLINE sourceUnfoldr #-}
136sourceUnfoldr :: (Monad m, S.IsStream t) => Int -> t m Int
137sourceUnfoldr n = S.unfoldr step n
138 where
139 step cnt =
140 if cnt > n + value
141 then Nothing
142 else (Just (cnt, cnt + 1))
144{-# INLINE sourceUnfoldrM #-}
145sourceUnfoldrM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
146sourceUnfoldrM n = S.unfoldrM step n
147 where
148 step cnt =
149 if cnt > n + value
150 then return Nothing
151 else return (Just (cnt, cnt + 1))
153{-# INLINE sourceUnfoldrMAction #-}
154sourceUnfoldrMAction :: (S.IsStream t, S.MonadAsync m) => Int -> t m (m Int)
155sourceUnfoldrMAction n = S.serially $ S.unfoldrM step n
156 where
157 step cnt =
158 if cnt > n + value
159 then return Nothing
160 else return (Just (return cnt, cnt + 1))
162-------------------------------------------------------------------------------
163-- Elimination
164-------------------------------------------------------------------------------
166{-# INLINE runStream #-}
167runStream :: Monad m => Stream m a -> m ()
168runStream = S.runStream
170toNull t = runStream . t
171uncons s = do
172 r <- S.uncons s
173 case r of
174 Nothing -> return ()
175 Just (_, t) -> uncons t
176nullHeadTail s = do
177 r <- S.null s
178 if not r
179 then do
180 _ <- S.head s
181 t <- S.tail s
182 case t of
183 Nothing -> return ()
184 Just x -> nullHeadTail x
185 else return ()
186mapM_ = S.mapM_ (\_ -> return ())
187toList = S.toList
188foldr = S.foldr (:) []
189foldrM = S.foldrM (\a xs -> return (a : xs)) []
190foldl = S.foldl' (+) 0
191last = S.last
192elem = S.elem maxValue
193notElem = S.notElem maxValue
194length = S.length
195all = S.all (<= maxValue)
196any = S.any (> maxValue)
197maximum = S.maximum
198minimum = S.minimum
199sum = S.sum
200product = S.product
202-------------------------------------------------------------------------------
203-- Transformation
204-------------------------------------------------------------------------------
206{-# INLINE transform #-}
207transform :: Monad m => Stream m a -> m ()
208transform = runStream
210scan = transform . S.scanl' (+) 0
211fmap = transform . Prelude.fmap (+1)
212map = transform . S.map (+1)
213mapM t = transform . t . S.mapM return
214mapMaybe = transform . S.mapMaybe
215 (\x -> if Prelude.odd x then Nothing else Just ())
216mapMaybeM = transform . S.mapMaybeM
217 (\x -> if Prelude.odd x then (return Nothing) else return $ Just ())
218sequence t = transform . t . S.sequence
219filterEven = transform . S.filter even
220filterAllOut = transform . S.filter (> maxValue)
221filterAllIn = transform . S.filter (<= maxValue)
222takeOne = transform . S.take 1
223takeAll = transform . S.take maxValue
224takeWhileTrue = transform . S.takeWhile (<= maxValue)
225takeWhileMTrue = transform . S.takeWhileM (return . (<= maxValue))
226dropAll = transform . S.drop maxValue
227dropWhileTrue = transform . S.dropWhile (<= maxValue)
228dropWhileMTrue = transform . S.dropWhileM (return . (<= maxValue))
230-------------------------------------------------------------------------------
231-- Zipping and concat
232-------------------------------------------------------------------------------
234zip src = do
235 r <- S.tail src
236 let src1 = fromJust r
237 transform $ (S.zipWith (,) src src1)
238zipM src = do
239 r <- S.tail src
240 let src1 = fromJust r
241 transform $ (S.zipWithM (\a b -> return (a,b)) src src1)
242zipAsync src = do
243 r <- S.tail src
244 let src1 = fromJust r
245 transform $ (S.zipAsyncWith (,) src src1)
246zipAsyncM src = do
247 r <- S.tail src
248 let src1 = fromJust r
249 transform $ (S.zipAsyncWithM (\a b -> return (a,b)) src src1)
250concat _n = return ()
252-------------------------------------------------------------------------------
253-- Composition
254-------------------------------------------------------------------------------
256{-# INLINE compose #-}
257compose :: Monad m => (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
258compose f = transform . f . f . f . f
260composeMapM = compose (S.mapM return)
261composeAllInFilters = compose (S.filter (<= maxValue))
262composeAllOutFilters = compose (S.filter (> maxValue))
263composeMapAllInFilter =
264 compose (S.filter (<= maxValue) . Prelude.fmap (subtract 1))
266{-# INLINABLE composeScaling #-}
267composeScaling :: Monad m => Int -> Stream m Int -> m ()
268composeScaling m =
269 case m of
270 1 -> transform . f
271 2 -> transform . f . f
272 3 -> transform . f . f . f
273 4 -> transform . f . f . f . f
274 _ -> undefined
275 where f = S.filter (<= maxValue)