on master help sign in
Add mixed ops x 2 and iterated benchmarks to base

Also, fix comparative graph generation, titles etc.

commitbf4e5d89ec8ce9d05a6dc6361619bbe71fcb57ea authorHarendra Kumar <harendra.kumar@gmail.com> dateTue 6 Nov 2018, 03:12 (8 years ago) parent6279c37
6 files changed+296−59
benchmark/BaseStreams.hs+85−8 benchmark/Chart.hs+83−32 benchmark/Linear.hs+3−3 benchmark/LinearOps.hs+15−11 benchmark/StreamDOps.hs+54−2 benchmark/StreamKOps.hs+56−3
benchmark/BaseStreams.hs+85−8
@@ -19,11 +19,20 @@ import qualified StreamKOps as K
1919-- completely optimized out by the compiler in some cases.
2020{-# INLINE benchIO #-}
2121benchIO :: String -> (a IO Int -> IO ()) -> (Int -> a IO Int) -> Benchmark
22−benchIO name run f = bench name $ nfIO $ randomRIO (1,1000) >>= run . f
22+benchIO name run f = bench name $ nfIO $ randomRIO (1,1) >>= run . f
2323
2424benchFold :: NFData b
2525 => String -> (t IO Int -> IO b) -> (Int -> t IO Int) -> Benchmark
26−benchFold name f src = bench name $ nfIO $ randomRIO (1,1000) >>= f . src
26+benchFold name f src = bench name $ nfIO $ randomRIO (1,1) >>= f . src
27+
28+-- | Takes a source, and uses it with a default drain/fold method.
29+{-# INLINE benchD #-}
30+benchD :: String -> (Int -> D.Stream IO Int) -> Benchmark
31+benchD name f = bench name $ nfIO $ randomRIO (1,1) >>= D.toNull . f
32+
33+{-# INLINE benchK #-}
34+benchK :: String -> (Int -> K.Stream IO Int) -> Benchmark
35+benchK name f = bench name $ nfIO $ randomRIO (1,1) >>= K.toNull . f
2736
2837{-
2938_benchId :: NFData b => String -> (Ops.Stream m Int -> Identity b) -> Benchmark
@@ -60,7 +69,7 @@ main =
6069 , benchIO "mapMaybe" (D.mapMaybe 1) D.sourceUnfoldrM
6170 , benchIO "mapMaybeM" (D.mapMaybeM 1) D.sourceUnfoldrM
6271 ]
63− , bgroup "transformationN"
72+ , bgroup "transformationX4"
6473 [ benchIO "scan" (D.scan 4) D.sourceUnfoldrM
6574 , benchIO "map" (D.map 4) D.sourceUnfoldrM
6675 , benchIO "fmap" (D.fmap 4) D.sourceUnfoldrM
@@ -79,7 +88,7 @@ main =
7988 , benchIO "dropWhile-true" (D.dropWhileTrue 1) D.sourceUnfoldrM
8089 , benchIO "dropWhile-false" (D.dropWhileFalse 1) D.sourceUnfoldrM
8190 ]
82− , bgroup "filteringN"
91+ , bgroup "filteringX4"
8392 [ benchIO "filter-even" (D.filterEven 4) D.sourceUnfoldrM
8493 , benchIO "filter-all-out" (D.filterAllOut 4) D.sourceUnfoldrM
8594 , benchIO "filter-all-in" (D.filterAllIn 4) D.sourceUnfoldrM
@@ -91,7 +100,31 @@ main =
91100 , benchIO "dropWhile-false" (D.dropWhileFalse 4) D.sourceUnfoldrM
92101 ]
93102 , benchIO "zip" D.zip D.sourceUnfoldrM
94− , bgroup "composed"
103+ , bgroup "mixed"
104+ [ benchIO "scan-map" (D.scanMap 1) D.sourceUnfoldrM
105+ , benchIO "drop-map" (D.dropMap 1) D.sourceUnfoldrM
106+ , benchIO "drop-scan" (D.dropScan 1) D.sourceUnfoldrM
107+ , benchIO "take-drop" (D.takeDrop 1) D.sourceUnfoldrM
108+ , benchIO "take-scan" (D.takeScan 1) D.sourceUnfoldrM
109+ , benchIO "take-map" (D.takeMap 1) D.sourceUnfoldrM
110+ , benchIO "filter-drop" (D.filterDrop 1) D.sourceUnfoldrM
111+ , benchIO "filter-take" (D.filterTake 1) D.sourceUnfoldrM
112+ , benchIO "filter-scan" (D.filterScan 1) D.sourceUnfoldrM
113+ , benchIO "filter-map" (D.filterMap 1) D.sourceUnfoldrM
114+ ]
115+ , bgroup "mixedX2"
116+ [ benchIO "scan-map" (D.scanMap 2) D.sourceUnfoldrM
117+ , benchIO "drop-map" (D.dropMap 2) D.sourceUnfoldrM
118+ , benchIO "drop-scan" (D.dropScan 2) D.sourceUnfoldrM
119+ , benchIO "take-drop" (D.takeDrop 2) D.sourceUnfoldrM
120+ , benchIO "take-scan" (D.takeScan 2) D.sourceUnfoldrM
121+ , benchIO "take-map" (D.takeMap 2) D.sourceUnfoldrM
122+ , benchIO "filter-drop" (D.filterDrop 2) D.sourceUnfoldrM
123+ , benchIO "filter-take" (D.filterTake 2) D.sourceUnfoldrM
124+ , benchIO "filter-scan" (D.filterScan 2) D.sourceUnfoldrM
125+ , benchIO "filter-map" (D.filterMap 2) D.sourceUnfoldrM
126+ ]
127+ , bgroup "mixedX4"
95128 [ benchIO "scan-map" (D.scanMap 4) D.sourceUnfoldrM
96129 , benchIO "drop-map" (D.dropMap 4) D.sourceUnfoldrM
97130 , benchIO "drop-scan" (D.dropScan 4) D.sourceUnfoldrM
@@ -103,6 +136,15 @@ main =
103136 , benchIO "filter-scan" (D.filterScan 4) D.sourceUnfoldrM
104137 , benchIO "filter-map" (D.filterMap 4) D.sourceUnfoldrM
105138 ]
139+ , bgroup "iterated"
140+ [ benchD "mapM" D.iterateMapM
141+ , benchD "scan(1/10)" D.iterateScan
142+ , benchD "filterEven" D.iterateFilterEven
143+ , benchD "takeAll" D.iterateTakeAll
144+ , benchD "dropOne" D.iterateDropOne
145+ , benchD "dropWhileFalse(1/10)" D.iterateDropWhileFalse
146+ , benchD "dropWhileTrue" D.iterateDropWhileTrue
147+ ]
106148 ]
107149 , bgroup "streamK"
108150 [ bgroup "generation"
@@ -131,12 +173,14 @@ main =
131173 , bgroup "transformation"
132174 [ benchIO "scan" (K.scan 1) K.sourceUnfoldrM
133175 , benchIO "map" (K.map 1) K.sourceUnfoldrM
176+ , benchIO "fmap" (K.fmap 1) K.sourceUnfoldrM
134177 , benchIO "mapM" (K.mapM 1) K.sourceUnfoldrM
135178 -- , benchIO "concat" K.concat K.sourceUnfoldrM
136179 ]
137− , bgroup "transformationN"
180+ , bgroup "transformationX4"
138181 [ benchIO "scan" (K.scan 4) K.sourceUnfoldrM
139182 , benchIO "map" (K.map 4) K.sourceUnfoldrM
183+ , benchIO "fmap" (K.fmap 4) K.sourceUnfoldrM
140184 , benchIO "mapM" (K.mapM 4) K.sourceUnfoldrM
141185 -- , benchIO "concat" K.concat K.sourceUnfoldrM
142186 ]
@@ -151,7 +195,7 @@ main =
151195 , benchIO "dropWhile-true" (K.dropWhileTrue 1) K.sourceUnfoldrM
152196 , benchIO "dropWhile-false" (K.dropWhileFalse 1) K.sourceUnfoldrM
153197 ]
154− , bgroup "filteringN"
198+ , bgroup "filteringX4"
155199 [ benchIO "filter-even" (K.filterEven 4) K.sourceUnfoldrM
156200 , benchIO "filter-all-out" (K.filterAllOut 4) K.sourceUnfoldrM
157201 , benchIO "filter-all-in" (K.filterAllIn 4) K.sourceUnfoldrM
@@ -163,7 +207,31 @@ main =
163207 , benchIO "dropWhile-false" (K.dropWhileFalse 4) K.sourceUnfoldrM
164208 ]
165209 , benchIO "zip" K.zip K.sourceUnfoldrM
166− , bgroup "composed"
210+ , bgroup "mixed"
211+ [ benchIO "scan-map" (K.scanMap 1) K.sourceUnfoldrM
212+ , benchIO "drop-map" (K.dropMap 1) K.sourceUnfoldrM
213+ , benchIO "drop-scan" (K.dropScan 1) K.sourceUnfoldrM
214+ , benchIO "take-drop" (K.takeDrop 1) K.sourceUnfoldrM
215+ , benchIO "take-scan" (K.takeScan 1) K.sourceUnfoldrM
216+ , benchIO "take-map" (K.takeMap 1) K.sourceUnfoldrM
217+ , benchIO "filter-drop" (K.filterDrop 1) K.sourceUnfoldrM
218+ , benchIO "filter-take" (K.filterTake 1) K.sourceUnfoldrM
219+ , benchIO "filter-scan" (K.filterScan 1) K.sourceUnfoldrM
220+ , benchIO "filter-map" (K.filterMap 1) K.sourceUnfoldrM
221+ ]
222+ , bgroup "mixedX2"
223+ [ benchIO "scan-map" (K.scanMap 2) K.sourceUnfoldrM
224+ , benchIO "drop-map" (K.dropMap 2) K.sourceUnfoldrM
225+ , benchIO "drop-scan" (K.dropScan 2) K.sourceUnfoldrM
226+ , benchIO "take-drop" (K.takeDrop 2) K.sourceUnfoldrM
227+ , benchIO "take-scan" (K.takeScan 2) K.sourceUnfoldrM
228+ , benchIO "take-map" (K.takeMap 2) K.sourceUnfoldrM
229+ , benchIO "filter-drop" (K.filterDrop 2) K.sourceUnfoldrM
230+ , benchIO "filter-take" (K.filterTake 2) K.sourceUnfoldrM
231+ , benchIO "filter-scan" (K.filterScan 2) K.sourceUnfoldrM
232+ , benchIO "filter-map" (K.filterMap 2) K.sourceUnfoldrM
233+ ]
234+ , bgroup "mixedX4"
167235 [ benchIO "scan-map" (K.scanMap 4) K.sourceUnfoldrM
168236 , benchIO "drop-map" (K.dropMap 4) K.sourceUnfoldrM
169237 , benchIO "drop-scan" (K.dropScan 4) K.sourceUnfoldrM
@@ -175,5 +243,14 @@ main =
175243 , benchIO "filter-scan" (K.filterScan 4) K.sourceUnfoldrM
176244 , benchIO "filter-map" (K.filterMap 4) K.sourceUnfoldrM
177245 ]
246+ , bgroup "iterated"
247+ [ benchK "mapM" K.iterateMapM
248+ , benchK "scan(1/10)" K.iterateScan
249+ , benchK "filterEven" K.iterateFilterEven
250+ , benchK "takeAll" K.iterateTakeAll
251+ , benchK "dropOne" K.iterateDropOne
252+ , benchK "dropWhileFalse(1/10)" K.iterateDropWhileFalse
253+ , benchK "dropWhileTrue" K.iterateDropWhileTrue
254+ ]
178255 ]
179256 ]
benchmark/Chart.hs+83−32
@@ -7,8 +7,10 @@ module Main where
77import Control.Exception (handle, catch, SomeException, ErrorCall(..))
88import Control.Monad.Trans.State
99import Control.Monad.Trans.Maybe
10+import Data.Function (on, (&))
1011import Data.List
1112import Data.List.Split
13+import Data.Maybe (mapMaybe)
1214import Data.Ord (comparing)
1315import System.Environment (getArgs)
1416import Control.Monad.IO.Class (liftIO)
@@ -100,21 +102,21 @@ ignoringErr a = catch a (\(ErrorCall err :: ErrorCall) ->
100102------------------------------------------------------------------------------
101103
102104makeLinearGraphs :: Config -> String -> IO ()
103−makeLinearGraphs cfg inputFile = do
105+makeLinearGraphs cfg@Config{..} inputFile = do
104106 ignoringErr $ graph inputFile "generation" $ cfg
105− { title = Just "Generation"
107+ { title = (++) <$> title <*> Just " generation"
106108 , classifyBenchmark =
107109 fmap ("Streamly",) . stripPrefix "serially/generation/"
108110 }
109111
110112 ignoringErr $ graph inputFile "elimination" $ cfg
111− { title = Just "Elimination"
113+ { title = (++) <$> title <*> Just " Elimination"
112114 , classifyBenchmark =
113115 fmap ("Streamly",) . stripPrefix "serially/elimination/"
114116 }
115117
116118 ignoringErr $ graph inputFile "transformation-zip" $ cfg
117− { title = Just "Transformation & Zip"
119+ { title = (++) <$> title <*> Just " Transformation & Zip"
118120 , classifyBenchmark = \b ->
119121 if "serially/transformation/" `isPrefixOf` b
120122 || "serially/zip" `isPrefixOf` b
@@ -123,34 +125,34 @@ makeLinearGraphs cfg inputFile = do
123125 }
124126
125127 ignoringErr $ graph inputFile "filtering" $ cfg
126− { title = Just "Filtering"
128+ { title = (++) <$> title <*> Just " Filtering"
127129 , classifyBenchmark =
128130 fmap ("Streamly",) . stripPrefix "serially/filtering/"
129131 }
130132
131133 ignoringErr $ graph inputFile "transformationX4" $ cfg
132− { title = Just "Transformation x 4"
134+ { title = (++) <$> title <*> Just " Transformation x 4"
133135 , classifyBenchmark =
134136 fmap ("Streamly",) . stripPrefix "serially/transformationX4/"
135137 }
136138
137139 ignoringErr $ graph inputFile "filteringX4"
138140 $ cfg
139− { title = Just "Filtering x 4"
141+ { title = (++) <$> title <*> Just " Filtering x 4"
140142 , classifyBenchmark =
141143 fmap ("Streamly",) . stripPrefix "serially/filteringX4/"
142144 }
143145
144146 ignoringErr $ graph inputFile "mixedX4"
145147 $ cfg
146− { title = Just "Mixed x 4"
148+ { title = (++) <$> title <*> Just " Mixed x 4"
147149 , classifyBenchmark =
148150 fmap ("Streamly",) . stripPrefix "serially/mixedX4/"
149151 }
150152
151153 ignoringErr $ graph inputFile "iterated"
152154 $ cfg
153− { title = Just "Iterate 10 x 100000"
155+ { title = Just "iterate 10,000 times over 10 elems"
154156 , classifyBenchmark =
155157 fmap ("Streamly",) . stripPrefix "serially/iterated/"
156158 }
@@ -161,23 +163,61 @@ makeLinearGraphs cfg inputFile = do
161163
162164makeNestedGraphs :: Config -> String -> IO ()
163165makeNestedGraphs cfg inputFile =
164− ignoringErr $ graph inputFile "nested-serial" $ cfg
165− { title = Just "Nested serial"
166− , classifyBenchmark = \b ->
167− let ls = splitOn "/" b
168− in case head ls of
169− "serially" -> Just (head ls, last ls)
170− _ -> Nothing
166+ ignoringErr $ graph inputFile "nested-all" $ cfg
167+ { presentation = Groups Absolute
168+ , classifyBenchmark = classifyNested
169+ , selectGroups = \gs ->
170+ groupBy ((==) `on` snd) gs
171+ & fmap (\xs -> mapMaybe (\x -> (x,) <$> lookup x xs) order)
172+ & concat
171173 }
172174
175+ where
176+
177+ order = ["serially", "asyncly", "wAsyncly", "aheadly", "parallely"]
178+
179+ classifyNested b
180+ | "serially/" `isPrefixOf` b =
181+ ("serially",) <$> stripPrefix "serially/" b
182+ | "asyncly/" `isPrefixOf` b =
183+ ("asyncly",) <$> stripPrefix "asyncly/" b
184+ | "wAsyncly/" `isPrefixOf` b =
185+ ("wAsyncly",) <$> stripPrefix "wAsyncly/" b
186+ | "aheadly/" `isPrefixOf` b =
187+ ("aheadly",) <$> stripPrefix "aheadly/" b
188+ | "parallely/" `isPrefixOf` b =
189+ ("parallely",) <$> stripPrefix "parallely/" b
190+ | otherwise = Nothing
191+
173192------------------------------------------------------------------------------
174193-- Charts for parallel streams
175194------------------------------------------------------------------------------
176195
177196makeLinearAsyncGraphs :: Config -> String -> IO ()
178−makeLinearAsyncGraphs cfg inputFile = do
179− putStrLn "Not implemented"
180− return ()
197+makeLinearAsyncGraphs cfg inputFile =
198+ ignoringErr $ graph inputFile "linear-async" cfg
199+ { presentation = Groups Absolute
200+ , classifyBenchmark = classifyAsync
201+ , selectGroups = \gs ->
202+ groupBy ((==) `on` snd) gs
203+ & fmap (\xs -> mapMaybe (\x -> (x,) <$> lookup x xs) order)
204+ & concat
205+ }
206+
207+ where
208+
209+ order = ["asyncly", "wAsyncly", "aheadly", "parallely"]
210+
211+ classifyAsync b
212+ | "asyncly/" `isPrefixOf` b =
213+ ("asyncly",) <$> stripPrefix "asyncly/" b
214+ | "wAsyncly/" `isPrefixOf` b =
215+ ("wAsyncly",) <$> stripPrefix "wAsyncly/" b
216+ | "aheadly/" `isPrefixOf` b =
217+ ("aheadly",) <$> stripPrefix "aheadly/" b
218+ | "parallely/" `isPrefixOf` b =
219+ ("parallely",) <$> stripPrefix "parallely/" b
220+ | otherwise = Nothing
181221
182222makeLinearRateGraphs :: Config -> String -> IO ()
183223makeLinearRateGraphs cfg inputFile = do
@@ -188,18 +228,22 @@ makeLinearRateGraphs cfg inputFile = do
188228-- Reports/Charts for base streams
189229------------------------------------------------------------------------------
190230
191−classifyBase b
192− | "streamD/" `isPrefixOf` b = ("streamD",) <$> stripPrefix "streamD/" b
193− | "streamK/" `isPrefixOf` b = ("streamK",) <$> stripPrefix "streamK/" b
194− | otherwise = Nothing
195−
196231showStreamDVsK Options{..} cfg inp out =
197232 let cfg' = cfg { classifyBenchmark = classifyBase }
198233 in if genGraphs
199234 then ignoringErr $ graph inp "streamD-vs-streamK"
200− cfg' {outputDir = Just out}
235+ cfg' { outputDir = Just out
236+ , presentation = Groups Absolute
237+ }
201238 else ignoringErr $ report inp Nothing cfg'
202239
240+ where
241+
242+ classifyBase b
243+ | "streamD/" `isPrefixOf` b = ("streamD",) <$> stripPrefix "streamD/" b
244+ | "streamK/" `isPrefixOf` b = ("streamK",) <$> stripPrefix "streamK/" b
245+ | otherwise = Nothing
246+
203247showStreamD Options{..} cfg inp out =
204248 let cfg' = cfg { classifyBenchmark = classifyStreamD }
205249 in if genGraphs
@@ -258,27 +302,34 @@ main = do
258302 return ()
259303 Just opts@Options{..} ->
260304 case benchType of
261− Linear -> benchShow opts cfg makeLinearGraphs
305+ Linear -> benchShow opts cfg
306+ { title = Just "100,000 elems" }
307+ makeLinearGraphs
262308 "charts/linear/results.csv"
263309 "charts/linear"
264− LinearAsync -> benchShow opts cfg makeLinearAsyncGraphs
310+ LinearAsync -> benchShow opts cfg
311+ { title = Just "Async 10,000 elems" }
312+ makeLinearAsyncGraphs
265313 "charts/linear-async/results.csv"
266314 "charts/linear-async"
267315 LinearRate -> benchShow opts cfg makeLinearRateGraphs
268316 "charts/linear-rate/results.csv"
269317 "charts/linear-rate"
270− Nested -> benchShow opts cfg makeNestedGraphs
318+ Nested -> benchShow opts cfg
319+ { title = Just "Nested loops 100 x 100 elems" }
320+ makeNestedGraphs
271321 "charts/nested/results.csv"
272322 "charts/nested"
273− Base ->
323+ Base -> do
324+ let cfg' = cfg { title = Just "100,000 elems" }
274325 if groupDiff
275− then showStreamDVsK opts cfg
326+ then showStreamDVsK opts cfg'
276327 "charts/base/results.csv"
277328 "charts/base"
278329 else do
279− showStreamD opts cfg
330+ showStreamD opts cfg'
280331 "charts/base/results.csv"
281332 "charts/base"
282− showStreamK opts cfg
333+ showStreamK opts cfg'
283334 "charts/base/results.csv"
284335 "charts/base"
benchmark/Linear.hs+3−3
@@ -96,7 +96,7 @@ main =
9696 , benchIO "elemIndices" (Ops.elemIndices 1)
9797 -- , benchIO "concat" Ops.concat
9898 ]
99− , bgroup "transformationN"
99+ , bgroup "transformationX4"
100100 [ benchIO "scan" (Ops.scan 4)
101101 , benchIO "map" (Ops.map 4)
102102 , benchIO "fmap" (Ops.fmap 4)
@@ -122,7 +122,7 @@ main =
122122 --, benchIO "dropWhileM-true" (Ops.dropWhileMTrue 1)
123123 , benchIO "dropWhile-false" (Ops.dropWhileFalse 1)
124124 ]
125− , bgroup "filteringN"
125+ , bgroup "filteringX4"
126126 [ benchIO "filter-even" (Ops.filterEven 4)
127127 , benchIO "filter-all-out" (Ops.filterAllOut 4)
128128 , benchIO "filter-all-in" (Ops.filterAllIn 4)
@@ -137,7 +137,7 @@ main =
137137 ]
138138 , benchIO "zip" Ops.zip
139139 , benchIO "zipM" Ops.zipM
140− , bgroup "composed"
140+ , bgroup "mixedX4"
141141 [ benchIO "scan-map" (Ops.scanMap 4)
142142 , benchIO "drop-map" (Ops.dropMap 4)
143143 , benchIO "drop-scan" (Ops.dropScan 4)
benchmark/LinearOps.hs+15−11
@@ -16,7 +16,7 @@ import Data.Maybe (fromJust)
1616import Prelude
1717 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=), (==), (<=),
1818 subtract, undefined, Maybe(..), odd, Bool, not, (>>=), mapM_, curry,
19− maxBound)
19+ maxBound, div)
2020import qualified Prelude as P
2121
2222import qualified Streamly as S
@@ -287,7 +287,7 @@ dropOne n = composeN n $ S.drop 1
287287dropAll n = composeN n $ S.drop maxValue
288288dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
289289dropWhileMTrue n = composeN n $ S.dropWhileM (return . (<= maxValue))
290−dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
290+dropWhileFalse n = composeN n $ S.dropWhile (> maxValue)
291291findIndices n = composeN n $ S.findIndices (== maxValue)
292292elemIndices n = composeN n $ S.elemIndices maxValue
293293
@@ -295,11 +295,15 @@ elemIndices n = composeN n $ S.elemIndices maxValue
295295-- Iteration
296296-------------------------------------------------------------------------------
297297
298+iterStreamLen, maxIters :: Int
299+iterStreamLen = 10
300+maxIters = 10000
301+
298302{-# INLINE iterateSource #-}
299303iterateSource
300304 :: S.MonadAsync m
301305 => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
302−iterateSource g i n = f i (sourceUnfoldrMN 10 n)
306+iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
303307 where
304308 f (0 :: Int) m = g m
305309 f x m = g (f (x P.- 1) m)
@@ -317,14 +321,14 @@ iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
317321 => Int -> Stream m Int
318322
319323-- this is quadratic
320−iterateScan = iterateSource (S.scanl' (+) 0) 1000
321−
322−iterateMapM = iterateSource (S.mapM return) 100000
323−iterateFilterEven = iterateSource (S.filter even) 100000
324−iterateTakeAll = iterateSource (S.take maxValue) 100000
325−iterateDropOne = iterateSource (S.drop 1) 100000
326−iterateDropWhileFalse = iterateSource (S.dropWhile (<= 1)) 100000
327−iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) 100000
324+iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
325+
326+iterateMapM = iterateSource (S.mapM return) maxIters
327+iterateFilterEven = iterateSource (S.filter even) maxIters
328+iterateTakeAll = iterateSource (S.take maxValue) maxIters
329+iterateDropOne = iterateSource (S.drop 1) maxIters
330+iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue)) maxIters
331+iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
328332
329333-------------------------------------------------------------------------------
330334-- Zipping and concat
benchmark/StreamDOps.hs+54−2
@@ -6,15 +6,17 @@
66-- Maintainer : harendra.kumar@gmail.com
77
88{-# LANGUAGE FlexibleContexts #-}
9+{-# LANGUAGE ScopedTypeVariables #-}
910
1011module StreamDOps where
1112
1213import Control.Monad (when)
1314import Data.Maybe (isJust)
1415import Prelude
15− (Monad, Int, (+), ($), (.), return, (>), even, (<=),
16+ (Monad, Int, (+), ($), (.), return, (>), even, (<=), div,
1617 subtract, undefined, Maybe(..), not, mapM_, (>>=),
1718 maxBound, fmap, odd)
19+import qualified Prelude as P
1820
1921import qualified Streamly.Streams.StreamD as S
2022
@@ -63,6 +65,15 @@ sourceUnfoldr n = S.unfoldr step n
6365 then Nothing
6466 else Just (cnt, cnt + 1)
6567
68+{-# INLINE sourceUnfoldrMN #-}
69+sourceUnfoldrMN :: Monad m => Int -> Int -> Stream m Int
70+sourceUnfoldrMN m n = S.unfoldrM step n
71+ where
72+ step cnt =
73+ if cnt > n + m
74+ then return Nothing
75+ else return (Just (cnt, cnt + 1))
76+
6677{-# INLINE sourceUnfoldrM #-}
6778sourceUnfoldrM :: Monad m => Int -> Stream m Int
6879sourceUnfoldrM n = S.unfoldrM step n
@@ -141,6 +152,7 @@ composeN n f =
141152{-# INLINE fmap #-}
142153{-# INLINE mapM #-}
143154{-# INLINE mapMaybe #-}
155+{-# INLINE mapMaybeM #-}
144156{-# INLINE filterEven #-}
145157{-# INLINE filterAllOut #-}
146158{-# INLINE filterAllIn #-}
@@ -178,7 +190,47 @@ dropOne n = composeN n $ S.drop 1
178190dropAll n = composeN n $ S.drop maxValue
179191dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
180192dropWhileMTrue n = composeN n $ S.dropWhileM (return . (<= maxValue))
181−dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
193+dropWhileFalse n = composeN n $ S.dropWhile (> maxValue)
194+
195+-------------------------------------------------------------------------------
196+-- Iteration
197+-------------------------------------------------------------------------------
198+
199+iterStreamLen, maxIters :: Int
200+iterStreamLen = 10
201+maxIters = 10000
202+
203+{-# INLINE iterateSource #-}
204+iterateSource
205+ :: Monad m
206+ => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
207+iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
208+ where
209+ f (0 :: Int) m = g m
210+ f x m = g (f (x P.- 1) m)
211+
212+{-# INLINE iterateMapM #-}
213+{-# INLINE iterateScan #-}
214+{-# INLINE iterateFilterEven #-}
215+{-# INLINE iterateTakeAll #-}
216+{-# INLINE iterateDropOne #-}
217+{-# INLINE iterateDropWhileFalse #-}
218+{-# INLINE iterateDropWhileTrue #-}
219+iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
220+ iterateDropWhileFalse, iterateDropWhileTrue
221+ :: Monad m
222+ => Int -> Stream m Int
223+
224+-- this is quadratic
225+iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
226+iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
227+ (maxIters `div` 10)
228+
229+iterateMapM = iterateSource (S.mapM return) maxIters
230+iterateFilterEven = iterateSource (S.filter even) maxIters
231+iterateTakeAll = iterateSource (S.take maxValue) maxIters
232+iterateDropOne = iterateSource (S.drop 1) maxIters
233+iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
182234
183235-------------------------------------------------------------------------------
184236-- Zipping and concat
benchmark/StreamKOps.hs+56−3
@@ -6,15 +6,17 @@
66-- Maintainer : harendra.kumar@gmail.com
77
88{-# LANGUAGE FlexibleContexts #-}
9+{-# LANGUAGE ScopedTypeVariables #-}
910
1011module StreamKOps where
1112
1213import Control.Monad (when)
1314import Data.Maybe (isJust)
1415import Prelude
15− (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
16+ (Monad, Int, (+), ($), (.), return, even, (>), (<=), div,
1617 subtract, undefined, Maybe(..), not, mapM_, (>>=),
1718 maxBound)
19+import qualified Prelude as P
1820
1921import qualified Streamly.Streams.StreamK as S
2022import qualified Streamly.Streams.Prelude as S
@@ -69,6 +71,15 @@ sourceUnfoldrM n = S.unfoldrM step n
6971 then return Nothing
7072 else return (Just (cnt, cnt + 1))
7173
74+{-# INLINE sourceUnfoldrMN #-}
75+sourceUnfoldrMN :: S.MonadAsync m => Int -> Int -> Stream m Int
76+sourceUnfoldrMN m n = S.unfoldrM step n
77+ where
78+ step cnt =
79+ if cnt > n + m
80+ then return Nothing
81+ else return (Just (cnt, cnt + 1))
82+
7283{-
7384{-# INLINE sourceFromEnum #-}
7485sourceFromEnum :: Monad m => Int -> Stream m Int
@@ -156,6 +167,7 @@ composeN n f =
156167
157168{-# INLINE scan #-}
158169{-# INLINE map #-}
170+{-# INLINE fmap #-}
159171{-# INLINE filterEven #-}
160172{-# INLINE filterAllOut #-}
161173{-# INLINE filterAllIn #-}
@@ -166,7 +178,7 @@ composeN n f =
166178{-# INLINE dropAll #-}
167179{-# INLINE dropWhileTrue #-}
168180{-# INLINE dropWhileFalse #-}
169−scan, map, filterEven, filterAllOut,
181+scan, map, fmap, filterEven, filterAllOut,
170182 filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
171183 dropWhileTrue, dropWhileFalse
172184 :: Monad m
@@ -176,7 +188,8 @@ scan, map, filterEven, filterAllOut,
176188mapM :: S.MonadAsync m => Int -> Stream m Int -> m ()
177189
178190scan n = composeN n $ S.scanl' (+) 0
179−map n = composeN n $ fmap (+1)
191+map n = composeN n $ P.fmap (+1)
192+fmap n = composeN n $ P.fmap (+1)
180193mapM n = composeN n $ S.mapM return
181194filterEven n = composeN n $ S.filter even
182195filterAllOut n = composeN n $ S.filter (> maxValue)
@@ -189,6 +202,46 @@ dropAll n = composeN n $ S.drop maxValue
189202dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
190203dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
191204
205+-------------------------------------------------------------------------------
206+-- Iteration
207+-------------------------------------------------------------------------------
208+
209+iterStreamLen, maxIters :: Int
210+iterStreamLen = 10
211+maxIters = 10000
212+
213+{-# INLINE iterateSource #-}
214+iterateSource
215+ :: S.MonadAsync m
216+ => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
217+iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
218+ where
219+ f (0 :: Int) m = g m
220+ f x m = g (f (x P.- 1) m)
221+
222+{-# INLINE iterateMapM #-}
223+{-# INLINE iterateScan #-}
224+{-# INLINE iterateFilterEven #-}
225+{-# INLINE iterateTakeAll #-}
226+{-# INLINE iterateDropOne #-}
227+{-# INLINE iterateDropWhileFalse #-}
228+{-# INLINE iterateDropWhileTrue #-}
229+iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
230+ iterateDropWhileFalse, iterateDropWhileTrue
231+ :: S.MonadAsync m
232+ => Int -> Stream m Int
233+
234+-- this is quadratic
235+iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
236+iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
237+ (maxIters `div` 10)
238+
239+iterateMapM = iterateSource (S.mapM return) maxIters
240+iterateFilterEven = iterateSource (S.filter even) maxIters
241+iterateTakeAll = iterateSource (S.take maxValue) maxIters
242+iterateDropOne = iterateSource (S.drop 1) maxIters
243+iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
244+
192245-------------------------------------------------------------------------------
193246-- Zipping and concat
194247-------------------------------------------------------------------------------