on 01f0681 help sign in
streamly/benchmark/LinearOps.hs
177 lines 5.8 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 Prelude
13 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
14 subtract, undefined, Maybe(..), Monoid, foldMap)
16import qualified Streamly as S
17import qualified Streamly.Prelude as S
19value, appendValue, maxValue :: Int
20value = 1000000
21appendValue = 100000
22maxValue = value + 1000
24-------------------------------------------------------------------------------
25-- Benchmark ops
26-------------------------------------------------------------------------------
28{-# INLINE toNull #-}
29{-# INLINE toList #-}
30{-# INLINE foldl #-}
31{-# INLINE last #-}
32{-# INLINE scan #-}
33{-# INLINE map #-}
34{-# INLINE filterEven #-}
35{-# INLINE mapM #-}
36{-# INLINE filterAllOut #-}
37{-# INLINE filterAllIn #-}
38{-# INLINE takeOne #-}
39{-# INLINE takeAll #-}
40{-# INLINE takeWhileTrue #-}
41{-# INLINE dropAll #-}
42{-# INLINE dropWhileTrue #-}
43{-# INLINE zip #-}
44{-# INLINE concat #-}
45{-# INLINE composeMapM #-}
46{-# INLINE composeAllInFilters #-}
47{-# INLINE composeAllOutFilters #-}
48{-# INLINE composeMapAllInFilter #-}
49scan, map, filterEven, filterAllOut,
50 filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue, zip,
51 concat, composeAllInFilters, composeAllOutFilters,
52 composeMapAllInFilter
53 :: Monad m
54 => Stream m Int -> m ()
56mapM, composeMapM :: S.MonadAsync m => Stream m Int -> m ()
57toList :: Monad m => Stream m Int -> m [Int]
58foldl :: Monad m => Stream m Int -> m Int
59last :: Monad m => Stream m Int -> m (Maybe Int)
61toNull :: Monad m => (t m Int -> S.SerialT m Int) -> t m Int -> m ()
63-------------------------------------------------------------------------------
64-- Stream generation and elimination
65-------------------------------------------------------------------------------
67type Stream m a = S.SerialT m a
69{-# INLINE source #-}
70source :: S.IsStream t => Int -> t m Int
71source n = S.unfoldr step n
72 where
73 step cnt =
74 if cnt > n + value
75 then Nothing
76 else (Just (cnt, cnt + 1))
78{-# INLINE sourceFromFoldable #-}
79sourceFromFoldable :: S.IsStream t => Int -> t m Int
80sourceFromFoldable n = S.fromFoldable [n..n+value]
82{-# INLINE sourceFromFoldableM #-}
83sourceFromFoldableM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
84sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
86{-# INLINE sourceFoldMapWith #-}
87sourceFoldMapWith :: (S.IsStream t, Monad (t m), S.Semigroup (t m Int))
88 => Int -> t m Int
89sourceFoldMapWith n = S.foldMapWith (S.<>) return [n..n+value]
91{-# INLINE sourceFoldMapWithM #-}
92sourceFoldMapWithM :: (S.IsStream t, Monad m, S.Semigroup (t m Int))
93 => Int -> t m Int
94sourceFoldMapWithM n = S.foldMapWith (S.<>) (S.once . return) [n..n+value]
96{-# INLINE sourceUnfoldrM #-}
97sourceUnfoldrM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
98sourceUnfoldrM n = S.unfoldrM step n
99 where
100 step cnt =
101 if cnt > n + value
102 then return Nothing
103 else return (Just (cnt, cnt + 1))
105{-# INLINE runStream #-}
106runStream :: Monad m => Stream m a -> m ()
107runStream = S.runStream
109-------------------------------------------------------------------------------
110-- Elimination
111-------------------------------------------------------------------------------
113toNull t = runStream . t
114toList = S.toList
115foldl = S.foldl' (+) 0
116last = S.last
118-------------------------------------------------------------------------------
119-- Transformation
120-------------------------------------------------------------------------------
122{-# INLINE transform #-}
123transform :: Monad m => Stream m a -> m ()
124transform = runStream
126scan = transform . S.scanl' (+) 0
127map = transform . fmap (+1)
128mapM = transform . S.mapM return
129filterEven = transform . S.filter even
130filterAllOut = transform . S.filter (> maxValue)
131filterAllIn = transform . S.filter (<= maxValue)
132takeOne = transform . S.take 1
133takeAll = transform . S.take maxValue
134takeWhileTrue = transform . S.takeWhile (<= maxValue)
135dropAll = transform . S.drop maxValue
136dropWhileTrue = transform . S.dropWhile (<= maxValue)
138-------------------------------------------------------------------------------
139-- Zipping and concat
140-------------------------------------------------------------------------------
142zip src = transform $ (S.zipWith (,) src src)
143concat _n = return ()
145-------------------------------------------------------------------------------
146-- Append
147-------------------------------------------------------------------------------
149{-# INLINE append #-}
150append
151 :: (Monoid (t m Int), Monad m, Monad (t m))
152 => (t m Int -> S.SerialT m Int) -> Int -> m ()
153append t n = runStream $ t $ foldMap return [n..n+appendValue]
155-------------------------------------------------------------------------------
156-- Composition
157-------------------------------------------------------------------------------
159{-# INLINE compose #-}
160compose :: Monad m => (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
161compose f = transform . f . f . f . f
163composeMapM = compose (S.mapM return)
164composeAllInFilters = compose (S.filter (<= maxValue))
165composeAllOutFilters = compose (S.filter (> maxValue))
166composeMapAllInFilter = compose (S.filter (<= maxValue) . fmap (subtract 1))
168{-# INLINABLE composeScaling #-}
169composeScaling :: Monad m => Int -> Stream m Int -> m ()
170composeScaling m =
171 case m of
172 1 -> transform . f
173 2 -> transform . f . f
174 3 -> transform . f . f . f
175 4 -> transform . f . f . f . f
176 _ -> undefined
177 where f = S.filter (<= maxValue)