@@ -8,7 +8,6 @@
8{-# LANGUAGE CPP #-}
8{-# LANGUAGE CPP #-}
9{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE FlexibleContexts #-}
10{-# LANGUAGE ScopedTypeVariables #-}
10{-# LANGUAGE ScopedTypeVariables #-}
11−{-# OPTIONS_GHC -Wno-orphans #-}
13#ifdef __HADDOCK_VERSION__
12#ifdef __HADDOCK_VERSION__
14#undef INSPECTION
13#undef INSPECTION
@@ -21,23 +20,19 @@
22module Main (main) where
21module Main (main) where
24−#if !MIN_VERSION_base(4,18,0)
25−import Control.Applicative (liftA2)
27import Control.Monad (when)
23import Control.Monad (when)
28import Data.Maybe (isJust)
24import Data.Maybe (isJust)
29import System.Random (randomRIO)
25import System.Random (randomRIO)
30import Prelude hiding
26import Prelude hiding
31− ( Foldable(..), tail, mapM_, last, map, mapM, concatMap, zipWith, init, iterate
27+ (tail, mapM_, foldl, last, map, mapM, concatMap, zip, init)
35import qualified Prelude as P
29import qualified Prelude as P
36import qualified Data.List as List
30import qualified Data.List as List
38−import qualified Streamly.Internal.Data.StreamK as S
32+import qualified Streamly.Internal.Data.Stream.StreamK as S
33+import qualified Streamly.Internal.Data.SVar as S
40−import Test.Tasty.Bench (bench, nfIO, bgroup, Benchmark, defaultMain)
35+import Gauge (bench, nfIO, bgroup, Benchmark, defaultMain)
42import Streamly.Benchmark.Common
37import Streamly.Benchmark.Common
@@ -45,163 +40,112 @@ import Streamly.Benchmark.Common
45import Test.Inspection
40import Test.Inspection
48−{-
43+value, value2, value3, value16, maxValue :: Int
50−Benchmarks that need to be added
45+value2 = round (P.fromIntegral value**(1/2::P.Double)) -- double nested loop
51−
46+value3 = round (P.fromIntegral value**(1/3::P.Double)) -- triple nested loop
52−-- fromList
47+value16 = round (P.fromIntegral value**(1/16::P.Double)) -- triple nested loop
55−-- concatPairsWith
50+-------------------------------------------------------------------------------
56−-- apWith
51+-- Benchmark ops
57−-- apSerial
52+-------------------------------------------------------------------------------
58−-- apSerialDiscardFst
53+
59−-- apSerialDiscardSnd
54+{-# INLINE toNull #-}
60−
55+{-# INLINE uncons #-}
61−-- the
56+{-# INLINE nullTail #-}
62−-- serial
57+{-# INLINE headTail #-}
63−-- consMStream
58+{-# INLINE zip #-}
64−-- withLocal
59+toNull, uncons, nullTail, headTail, zip
66−
61+ => Stream m Int -> m ()
68−-- notElem
63+{-# INLINE toList #-}
69−-- all
64+toList :: Monad m => Stream m Int -> m [Int]
70−-- any
65+{-# INLINE foldl #-}
71−-- minimum
66+foldl :: Monad m => Stream m Int -> m Int
72−-- minimumBy
67+{-# INLINE last #-}
73−-- maximum
68+last :: Monad m => Stream m Int -> m (Maybe Int)
109−-- toStreamK (Probably can be skipped)
116-------------------------------------------------------------------------------
70-------------------------------------------------------------------------------
117-- Stream generation and elimination
71-- Stream generation and elimination
118-------------------------------------------------------------------------------
72-------------------------------------------------------------------------------
120−type Stream m a = S.StreamK m a
74+type Stream m a = S.Stream m a
76+{-# INLINE sourceUnfoldr #-}
77+sourceUnfoldr :: Int -> Stream m Int
78+sourceUnfoldr n = S.unfoldr step n
83+ else Just (cnt, cnt + 1)
122−{-# INLINE unfoldr #-}
85+{-# INLINE sourceUnfoldrN #-}
123−unfoldr :: Int -> Int -> Stream m Int
86+sourceUnfoldrN :: Int -> Int -> Stream m Int
124−unfoldr streamLen n = S.unfoldr step n
87+sourceUnfoldrN m n = S.unfoldr step n
126 step cnt =
89 step cnt =
127− if cnt > n + streamLen
90+ if cnt > n + m
128 then Nothing
91 then Nothing
129 else Just (cnt, cnt + 1)
92 else Just (cnt, cnt + 1)
131−{-# INLINE unfoldrM #-}
94+{-# INLINE sourceUnfoldrM #-}
132−unfoldrM :: Monad m => Int -> Int -> Stream m Int
95+sourceUnfoldrM :: S.MonadAsync m => Int -> Stream m Int
133−unfoldrM streamLen n = S.unfoldrMWith S.consM step n
96+sourceUnfoldrM n = S.unfoldrM step n
135 step cnt =
98 step cnt =
136− if cnt > n + streamLen
99+ if cnt > n + value
137 then return Nothing
100 then return Nothing
138 else return (Just (cnt, cnt + 1))
101 else return (Just (cnt, cnt + 1))
140−{-# INLINE repeat #-}
103+{-# INLINE sourceUnfoldrMN #-}
141−repeat :: Int -> Int -> Stream m Int
142−repeat streamLen = S.take streamLen . S.repeat
144−{-# INLINE repeatM #-}
145−repeatM :: Monad m => Int -> Int -> Stream m Int
104+sourceUnfoldrMN :: S.MonadAsync m => Int -> Int -> Stream m Int
146−repeatM streamLen = S.take streamLen . S.repeatM . return
105+sourceUnfoldrMN m n = S.unfoldrM step n
148−{-# INLINE replicate #-}
107+ step cnt =
149−replicate :: Int -> Int -> Stream m Int
108+ if cnt > n + m
150−replicate = S.replicate
109+ then return Nothing
151−
110+ else return (Just (cnt, cnt + 1))
152−{-# INLINE replicateM #-}
153−replicateM :: Monad m => Int -> Int -> Stream m Int
154−replicateM streamLen = S.replicateMWith S.consM streamLen . return
156−{-# INLINE iterate #-}
112+{-# INLINE sourceFromFoldable #-}
157−iterate :: Int -> Int -> Stream m Int
113+sourceFromFoldable :: Int -> Stream m Int
158−iterate streamLen = S.take streamLen . S.iterate (+1)
114+sourceFromFoldable n = S.fromFoldable [n..n+value]
160−{-# INLINE iterateM #-}
116+{-# INLINE sourceFromFoldableM #-}
161−iterateM :: Monad m => Int -> Int -> Stream m Int
117+sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
162−iterateM streamLen = S.take streamLen . S.iterateM (return . (+1)) . return
118+sourceFromFoldableM n =
119+ Prelude.foldr S.consM S.nil (Prelude.fmap return [n..n+value])
164−{-# INLINE fromFoldable #-}
121+{-# INLINABLE concatMapFoldableWith #-}
165−fromFoldable :: Int -> Int -> Stream m Int
122+concatMapFoldableWith :: (S.IsStream t, Foldable f)
166−fromFoldable streamLen n = S.fromFoldable [n..n+streamLen]
123+ => (t m b -> t m b -> t m b) -> (a -> t m b) -> f a -> t m b
124+concatMapFoldableWith f g = Prelude.foldr (f . g) S.nil
168−{-# INLINE fromFoldableM #-}
126+{-# INLINE sourceFoldMapWith #-}
169−fromFoldableM :: Monad m => Int -> Int -> Stream m Int
127+sourceFoldMapWith :: Int -> Stream m Int
170−fromFoldableM streamLen n =
128+sourceFoldMapWith n = concatMapFoldableWith S.serial S.yield [n..n+value]
171− List.foldr S.consM S.nil (Prelude.fmap return [n..n+streamLen])
173−{-# INLINABLE concatMapFoldableWith #-}
130+{-# INLINE sourceFoldMapWithM #-}
174−concatMapFoldableWith :: P.Foldable f
175− => (Stream m b -> Stream m b -> Stream m b)
176− -> (a -> Stream m b)
179−concatMapFoldableWith f g = P.foldr (f . g) S.nil
181−{-# INLINE concatMapFoldableSerial #-}
182−concatMapFoldableSerial :: Int -> Int -> Stream m Int
183−concatMapFoldableSerial streamLen n =
184− concatMapFoldableWith S.append S.fromPure [n..n+streamLen]
186−{-# INLINE concatMapFoldableSerialM #-}
187−concatMapFoldableSerialM :: Monad m => Int -> Int -> Stream m Int
131+sourceFoldMapWithM :: Monad m => Int -> Stream m Int
188−concatMapFoldableSerialM streamLen n =
132+sourceFoldMapWithM n =
189− concatMapFoldableWith S.append (S.fromEffect . return) [n..n+streamLen]
133+ concatMapFoldableWith S.serial (S.yieldM . return) [n..n+value]
191-------------------------------------------------------------------------------
135-------------------------------------------------------------------------------
192-- Elimination
136-- Elimination
193-------------------------------------------------------------------------------
137-------------------------------------------------------------------------------
195−{-# INLINE drain #-}
139+{-# INLINE runStream #-}
196−drain :: Monad m => Stream m a -> m ()
140+runStream :: Monad m => Stream m a -> m ()
197−drain = S.drain
141+runStream = S.drain
142+-- runStream = S.mapM_ (\_ -> return ())
199{-# INLINE mapM_ #-}
144{-# INLINE mapM_ #-}
200mapM_ :: Monad m => Stream m a -> m ()
145mapM_ :: Monad m => Stream m a -> m ()
201mapM_ = S.mapM_ (\_ -> return ())
146mapM_ = S.mapM_ (\_ -> return ())
203−{-# INLINE uncons #-}
148+toNull = runStream
204−uncons :: Monad m => Stream m Int -> m ()
205uncons s = do
149uncons s = do
206 r <- S.uncons s
150 r <- S.uncons s
207 case r of
151 case r of
@@ -209,238 +153,167 @@ uncons s = do
209 Just (_, t) -> uncons t
153 Just (_, t) -> uncons t
211{-# INLINE init #-}
155{-# INLINE init #-}
212−init :: Monad m => Stream m a -> m ()
156+init :: (Monad m, S.IsStream t) => t m a -> m ()
213init s = do
157init s = do
214 t <- S.init s
158 t <- S.init s
215 P.mapM_ S.drain t
159 P.mapM_ S.drain t
217{-# INLINE tail #-}
161{-# INLINE tail #-}
218−tail :: Monad m => Stream m a -> m ()
162+tail :: (Monad m, S.IsStream t) => t m a -> m ()
219tail s = S.tail s >>= P.mapM_ tail
163tail s = S.tail s >>= P.mapM_ tail
221−{-# INLINE nullTail #-}
222−nullTail :: Monad m => Stream m Int -> m ()
223nullTail s = do
165nullTail s = do
224 r <- S.null s
166 r <- S.null s
225 when (not r) $ S.tail s >>= P.mapM_ nullTail
167 when (not r) $ S.tail s >>= P.mapM_ nullTail
227−{-# INLINE headTail #-}
228−headTail :: Monad m => Stream m Int -> m ()
229headTail s = do
169headTail s = do
230 h <- S.head s
170 h <- S.head s
231 when (isJust h) $ S.tail s >>= P.mapM_ headTail
171 when (isJust h) $ S.tail s >>= P.mapM_ headTail
233−{-# INLINE toList #-}
234−toList :: Monad m => Stream m Int -> m [Int]
235toList = S.toList
173toList = S.toList
237−{-# INLINE foldl' #-}
238−foldl' :: Monad m => Stream m Int -> m Int
239−foldl' = S.foldl' (+) 0
174+foldl = S.foldl' (+) 0
242−last :: Monad m => Stream m Int -> m (Maybe Int)
243−last = S.last
175+last = S.last
245-------------------------------------------------------------------------------
177-------------------------------------------------------------------------------
246-- Transformation
178-- Transformation
247-------------------------------------------------------------------------------
179-------------------------------------------------------------------------------
181+{-# INLINE transform #-}
182+transform :: Monad m => Stream m a -> m ()
183+transform = runStream
249{-# INLINE composeN #-}
185{-# INLINE composeN #-}
251 :: Monad m
187 :: Monad m
252 => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
188 => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
253composeN n f =
189composeN n f =
254 case n of
190 case n of
255− 1 -> drain . f
191+ 1 -> transform . f
256− 2 -> drain . f . f
192+ 2 -> transform . f . f
257− 3 -> drain . f . f . f
193+ 3 -> transform . f . f . f
258− 4 -> drain . f . f . f . f
194+ 4 -> transform . f . f . f . f
259 _ -> undefined
195 _ -> undefined
261−{-# INLINE scanl' #-}
197+{-# INLINE scan #-}
262−scanl' :: Monad m => Int -> Stream m Int -> m ()
263−scanl' n = composeN n $ S.scanl' (+) 0
265{-# INLINE map #-}
198{-# INLINE map #-}
266−map :: Monad m => Int -> Stream m Int -> m ()
267−map n = composeN n $ S.map (+ 1)
269{-# INLINE fmapK #-}
199{-# INLINE fmapK #-}
270−fmapK :: Monad m => Int -> Stream m Int -> m ()
271−fmapK n = composeN n $ P.fmap (+ 1)
274−mapM :: Monad m => Int -> Stream m Int -> m ()
275−mapM n = composeN n $ S.mapMWith S.consM return
277−{-# INLINE mapMSerial #-}
278−mapMSerial :: Monad m => Int -> Stream m Int -> m ()
279−mapMSerial n = composeN n $ S.mapMSerial return
281{-# INLINE filterEven #-}
200{-# INLINE filterEven #-}
282−filterEven :: Monad m => Int -> Stream m Int -> m ()
283−filterEven n = composeN n $ S.filter even
285{-# INLINE filterAllOut #-}
201{-# INLINE filterAllOut #-}
286−filterAllOut :: Monad m => Int -> Int -> Stream m Int -> m ()
287−filterAllOut streamLen n = composeN n $ S.filter (> streamLen)
289{-# INLINE filterAllIn #-}
202{-# INLINE filterAllIn #-}
290−filterAllIn :: Monad m => Int -> Int -> Stream m Int -> m ()
291−filterAllIn streamLen n = composeN n $ S.filter (<= streamLen)
293{-# INLINE _takeOne #-}
203{-# INLINE _takeOne #-}
294−_takeOne :: Monad m => Int -> Stream m Int -> m ()
295−_takeOne n = composeN n $ S.take 1
297{-# INLINE takeAll #-}
204{-# INLINE takeAll #-}
298−takeAll :: Monad m => Int -> Int -> Stream m Int -> m ()
299−takeAll streamLen n = composeN n $ S.take streamLen
301{-# INLINE takeWhileTrue #-}
205{-# INLINE takeWhileTrue #-}
302−takeWhileTrue :: Monad m => Int -> Int -> Stream m Int -> m ()
303−takeWhileTrue streamLen n = composeN n $ S.takeWhile (<= streamLen)
305{-# INLINE dropOne #-}
206{-# INLINE dropOne #-}
306−dropOne :: Monad m => Int -> Stream m Int -> m ()
307−dropOne n = composeN n $ S.drop 1
309{-# INLINE dropAll #-}
207{-# INLINE dropAll #-}
310−dropAll :: Monad m => Int -> Int -> Stream m Int -> m ()
311−dropAll streamLen n = composeN n $ S.drop streamLen
313{-# INLINE dropWhileTrue #-}
208{-# INLINE dropWhileTrue #-}
314−dropWhileTrue :: Monad m => Int -> Int -> Stream m Int -> m ()
315−dropWhileTrue streamLen n = composeN n $ S.dropWhile (<= streamLen)
317{-# INLINE dropWhileFalse #-}
209{-# INLINE dropWhileFalse #-}
318−dropWhileFalse :: Monad m => Int -> Stream m Int -> m ()
319−dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
321{-# INLINE foldrS #-}
210{-# INLINE foldrS #-}
322−foldrS :: Monad m => Int -> Stream m Int -> m ()
323−foldrS n = composeN n $ S.foldrS S.cons S.nil
325{-# INLINE foldlS #-}
211{-# INLINE foldlS #-}
212+scan, map, fmapK, filterEven, filterAllOut,
213+ filterAllIn, _takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
214+ dropWhileTrue, dropWhileFalse, foldrS, foldlS
326−foldlS :: Monad m => Int -> Stream m Int -> m ()
216+ => Int -> Stream m Int -> m ()
327−foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
219+{-# INLINE mapMSerial #-}
329{-# INLINE intersperse #-}
220{-# INLINE intersperse #-}
221+mapM, mapMSerial, intersperse
330−intersperse :: Monad m => Int -> Int -> Stream m Int -> m ()
222+ :: S.MonadAsync m => Int -> Stream m Int -> m ()
331−intersperse streamLen n = composeN n $ S.intersperse streamLen
223+
224+scan n = composeN n $ S.scanl' (+) 0
225+map n = composeN n $ P.fmap (+1)
226+fmapK n = composeN n $ P.fmap (+1)
227+mapM n = composeN n $ S.mapM return
228+mapMSerial n = composeN n $ S.mapMSerial return
229+filterEven n = composeN n $ S.filter even
230+filterAllOut n = composeN n $ S.filter (> maxValue)
231+filterAllIn n = composeN n $ S.filter (<= maxValue)
232+_takeOne n = composeN n $ S.take 1
233+takeAll n = composeN n $ S.take maxValue
234+takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
235+dropOne n = composeN n $ S.drop 1
236+dropAll n = composeN n $ S.drop maxValue
237+dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
238+dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
239+foldrS n = composeN n $ S.foldrS S.cons S.nil
240+foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
241+intersperse n = composeN n $ S.intersperse maxValue
333-------------------------------------------------------------------------------
243-------------------------------------------------------------------------------
334-- Iteration
244-- Iteration
335-------------------------------------------------------------------------------
245-------------------------------------------------------------------------------
247+iterStreamLen, maxIters :: Int
337{-# INLINE iterateSource #-}
251{-# INLINE iterateSource #-}
338iterateSource
252iterateSource
339− :: Monad m => Int -> (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
254+ => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
340−iterateSource iterStreamLen g i n = f i (unfoldrM iterStreamLen n)
255+iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
342 f (0 :: Int) m = g m
257 f (0 :: Int) m = g m
343 f x m = g (f (x P.- 1) m)
258 f x m = g (f (x P.- 1) m)
346−{-# INLINE iterateScan #-}
347−iterateScan :: Monad m => Int -> Int -> Int -> Stream m Int
348−iterateScan iterStreamLen maxIters =
349− iterateSource iterStreamLen (S.scanl' (+) 0) (maxIters `div` 10)
352−{-# INLINE iterateDropWhileFalse #-}
353−iterateDropWhileFalse :: Monad m => Int -> Int -> Int -> Int -> Stream m Int
354−iterateDropWhileFalse streamLen iterStreamLen maxIters =
355− iterateSource iterStreamLen (S.dropWhile (> streamLen)) (maxIters `div` 10)
357{-# INLINE iterateMapM #-}
260{-# INLINE iterateMapM #-}
358−iterateMapM :: Monad m => Int -> Int -> Int -> Stream m Int
261+{-# INLINE iterateScan #-}
359−iterateMapM iterStreamLen =
360− iterateSource iterStreamLen (S.mapMWith S.consM return)
362{-# INLINE iterateFilterEven #-}
262{-# INLINE iterateFilterEven #-}
363−iterateFilterEven :: Monad m => Int -> Int -> Int -> Stream m Int
364−iterateFilterEven iterStreamLen = iterateSource iterStreamLen (S.filter even)
366{-# INLINE iterateTakeAll #-}
263{-# INLINE iterateTakeAll #-}
367−iterateTakeAll :: Monad m => Int -> Int -> Int -> Int -> Stream m Int
368−iterateTakeAll streamLen iterStreamLen =
369− iterateSource iterStreamLen (S.take streamLen)
371{-# INLINE iterateDropOne #-}
264{-# INLINE iterateDropOne #-}
372−iterateDropOne :: Monad m => Int -> Int -> Int -> Stream m Int
265+{-# INLINE iterateDropWhileFalse #-}
373−iterateDropOne iterStreamLen = iterateSource iterStreamLen (S.drop 1)
375{-# INLINE iterateDropWhileTrue #-}
266{-# INLINE iterateDropWhileTrue #-}
376−iterateDropWhileTrue ::
267+iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
268+ iterateDropWhileFalse, iterateDropWhileTrue
377− Monad m => Int -> Int -> Int -> Int -> Stream m Int
270+ => Int -> Stream m Int
378−iterateDropWhileTrue streamLen iterStreamLen =
271+
379− iterateSource iterStreamLen (S.dropWhile (<= streamLen))
272+-- this is quadratic
273+iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
274+iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
277+iterateMapM = iterateSource (S.mapM return) maxIters
278+iterateFilterEven = iterateSource (S.filter even) maxIters
279+iterateTakeAll = iterateSource (S.take maxValue) maxIters
280+iterateDropOne = iterateSource (S.drop 1) maxIters
281+iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
381-------------------------------------------------------------------------------
283-------------------------------------------------------------------------------
382-- Zipping
284-- Zipping
383-------------------------------------------------------------------------------
285-------------------------------------------------------------------------------
385−{-# INLINE zipWith #-}
386−zipWith :: Monad m => Stream m Int -> m ()
387−zipWith src = drain $ S.zipWith (,) src src
287+zip src = transform $ S.zipWith (,) src src
389−{-# INLINE zipWithM #-}
390−zipWithM :: Monad m => Stream m Int -> m ()
391−zipWithM src = drain $ S.zipWithM (curry return) src src
393−{-# INLINE sortByK #-}
394−sortByK :: (a -> a -> Ordering) -> Stream m a -> Stream m a
395−sortByK f = S.mergeMapWith (S.mergeBy f) S.fromPure
397−{-# INLINE sortBy #-}
398−sortBy :: Monad m => Stream m Int -> m ()
399−sortBy = drain . sortByK compare
401-------------------------------------------------------------------------------
289-------------------------------------------------------------------------------
402-- Mixed Composition
290-- Mixed Composition
403-------------------------------------------------------------------------------
291-------------------------------------------------------------------------------
405{-# INLINE scanMap #-}
293{-# INLINE scanMap #-}
406−scanMap :: Monad m => Int -> Stream m Int -> m ()
407−scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
409{-# INLINE dropMap #-}
294{-# INLINE dropMap #-}
410−dropMap :: Monad m => Int -> Stream m Int -> m ()
411−dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
413{-# INLINE dropScan #-}
295{-# INLINE dropScan #-}
414−dropScan :: Monad m => Int -> Stream m Int -> m ()
415−dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
417{-# INLINE takeDrop #-}
296{-# INLINE takeDrop #-}
418−takeDrop :: Monad m => Int -> Int -> Stream m Int -> m ()
419−takeDrop streamLen n = composeN n $ S.drop 1 . S.take streamLen
421{-# INLINE takeScan #-}
297{-# INLINE takeScan #-}
422−takeScan :: Monad m => Int -> Int -> Stream m Int -> m ()
423−takeScan streamLen n = composeN n $ S.scanl' (+) 0 . S.take streamLen
425{-# INLINE takeMap #-}
298{-# INLINE takeMap #-}
426−takeMap :: Monad m => Int -> Int -> Stream m Int -> m ()
427−takeMap streamLen n = composeN n $ S.map (subtract 1) . S.take streamLen
429{-# INLINE filterDrop #-}
299{-# INLINE filterDrop #-}
430−filterDrop :: Monad m => Int -> Int -> Stream m Int -> m ()
431−filterDrop streamLen n = composeN n $ S.drop 1 . S.filter (<= streamLen)
433{-# INLINE filterTake #-}
300{-# INLINE filterTake #-}
434−filterTake :: Monad m => Int -> Int -> Stream m Int -> m ()
435−filterTake streamLen n = composeN n $ S.take streamLen . S.filter (<= streamLen)
437{-# INLINE filterScan #-}
301{-# INLINE filterScan #-}
438−filterScan :: Monad m => Int -> Stream m Int -> m ()
439−filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
441{-# INLINE filterMap #-}
302{-# INLINE filterMap #-}
303+scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
304+ filterTake, filterScan, filterMap
442−filterMap :: Monad m => Int -> Int -> Stream m Int -> m ()
305+ :: Monad m => Int -> Stream m Int -> m ()
307+scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
443−filterMap streamLen n = composeN n $ S.map (subtract 1) . S.filter (<= streamLen)
308+dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
309+dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
310+takeDrop n = composeN n $ S.drop 1 . S.take maxValue
311+takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
312+takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
313+filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
314+filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
315+filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
316+filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
445-------------------------------------------------------------------------------
318-------------------------------------------------------------------------------
446-- ConcatMap
319-- ConcatMap
@@ -452,8 +325,8 @@ filterMap streamLen n = composeN n $ S.map (subtract 1) . S.filter (<= streamLen
452concatMap :: Int -> Int -> Int -> IO ()
325concatMap :: Int -> Int -> Int -> IO ()
453concatMap outer inner n =
326concatMap outer inner n =
454 S.drain $ S.concatMap
327 S.drain $ S.concatMap
455− (\_ -> unfoldrM inner n)
328+ (\_ -> sourceUnfoldrMN inner n)
456− (unfoldrM outer n)
329+ (sourceUnfoldrMN outer n)
458#ifdef INSPECTION
331#ifdef INSPECTION
459inspect $ hasNoTypeClasses 'concatMap
332inspect $ hasNoTypeClasses 'concatMap
@@ -465,8 +338,8 @@ inspect $ hasNoTypeClasses 'concatMap
465concatMapPure :: Int -> Int -> Int -> IO ()
338concatMapPure :: Int -> Int -> Int -> IO ()
466concatMapPure outer inner n =
339concatMapPure outer inner n =
467 S.drain $ S.concatMap
340 S.drain $ S.concatMap
468− (\_ -> unfoldr inner n)
341+ (\_ -> sourceUnfoldrN inner n)
469− (unfoldr outer n)
342+ (sourceUnfoldrN outer n)
471#ifdef INSPECTION
344#ifdef INSPECTION
472inspect $ hasNoTypeClasses 'concatMapPure
345inspect $ hasNoTypeClasses 'concatMapPure
@@ -477,7 +350,7 @@ inspect $ hasNoTypeClasses 'concatMapPure
477{-# INLINE concatMapRepl #-}
350{-# INLINE concatMapRepl #-}
478concatMapRepl :: Int -> Int -> Int -> IO ()
351concatMapRepl :: Int -> Int -> Int -> IO ()
479concatMapRepl outer inner n =
352concatMapRepl outer inner n =
480− S.drain $ S.concatMap (S.replicate inner) (unfoldrM outer n)
353+ S.drain $ S.concatMap (S.replicate inner) (sourceUnfoldrMN outer n)
482#ifdef INSPECTION
355#ifdef INSPECTION
483inspect $ hasNoTypeClasses 'concatMapRepl
356inspect $ hasNoTypeClasses 'concatMapRepl
@@ -489,70 +362,44 @@ inspect $ hasNoTypeClasses 'concatMapRepl
489sourceConcatMapId :: Monad m
362sourceConcatMapId :: Monad m
490 => Int -> Int -> Stream m (Stream m Int)
363 => Int -> Int -> Stream m (Stream m Int)
491sourceConcatMapId val n =
364sourceConcatMapId val n =
492− S.fromFoldable $ fmap (S.fromEffect . return) [n..n+val]
365+ S.fromFoldable $ fmap (S.yieldM . return) [n..n+val]
494−{-# INLINE concatMapBySerial #-}
367+{-# INLINE concatStreamsWith #-}
495−concatMapBySerial :: Int -> Int -> Int -> IO ()
368+concatStreamsWith :: Int -> Int -> Int -> IO ()
496−concatMapBySerial outer inner n =
369+concatStreamsWith outer inner n =
497− S.drain $ S.concatMapWith S.append
370+ S.drain $ S.concatMapBy S.serial
498− (unfoldrM inner)
371+ (sourceUnfoldrMN inner)
499− (unfoldrM outer n)
372+ (sourceUnfoldrMN outer n)
501-------------------------------------------------------------------------------
374-------------------------------------------------------------------------------
502-- Nested Composition
375-- Nested Composition
503-------------------------------------------------------------------------------
376-------------------------------------------------------------------------------
505−instance Monad m => Applicative (S.StreamK m) where
506− {-# INLINE pure #-}
378+{-# INLINE toNullApNested #-}
509− {-# INLINE (<*>) #-}
510− (<*>) = S.crossApply
512− {-# INLINE liftA2 #-}
513− liftA2 f x = (<*>) (fmap f x)
516− (*>) = S.crossApplySnd
519− (<*) = S.crossApplyFst
521−-- NOTE: even though concatMap for StreamD is 3x faster compared to StreamK,
522−-- the monad instance of StreamD is slower than StreamK after foldr/build
524−instance Monad m => Monad (S.StreamK m) where
525− {-# INLINE return #-}
528− {-# INLINE (>>=) #-}
529− (>>=) = flip S.concatMap
531−{-# INLINE drainApplicative #-}
532−drainApplicative :: Monad m => Stream m Int -> m ()
379+toNullApNested :: Monad m => Stream m Int -> m ()
533−drainApplicative s = drain $ do
380+toNullApNested s = runStream $ do
534 (+) <$> s <*> s
381 (+) <$> s <*> s
536−{-# INLINE drainMonad #-}
383+{-# INLINE toNullNested #-}
537−drainMonad :: Monad m => Stream m Int -> m ()
384+toNullNested :: Monad m => Stream m Int -> m ()
538−drainMonad s = drain $ do
385+toNullNested s = runStream $ do
541 return $ x + y
388 return $ x + y
543−{-# INLINE drainMonad3 #-}
390+{-# INLINE toNullNested3 #-}
544−drainMonad3 :: Monad m => Stream m Int -> m ()
391+toNullNested3 :: Monad m => Stream m Int -> m ()
545−drainMonad3 s = drain $ do
392+toNullNested3 s = runStream $ do
549 return $ x + y + z
396 return $ x + y + z
551−{-# INLINE filterAllOutMonad #-}
398+{-# INLINE filterAllOutNested #-}
552−filterAllOutMonad
399+filterAllOutNested
553 :: Monad m
400 :: Monad m
554 => Stream m Int -> m ()
401 => Stream m Int -> m ()
555−filterAllOutMonad str = drain $ do
402+filterAllOutNested str = runStream $ do
558 let s = x + y
405 let s = x + y
@@ -560,11 +407,11 @@ filterAllOutMonad str = drain $ do
560 then return s
407 then return s
561 else S.nil
408 else S.nil
563−{-# INLINE filterAllInMonad #-}
410+{-# INLINE filterAllInNested #-}
564−filterAllInMonad
411+filterAllInNested
565 :: Monad m
412 :: Monad m
566 => Stream m Int -> m ()
413 => Stream m Int -> m ()
567−filterAllInMonad str = drain $ do
414+filterAllInNested str = runStream $ do
570 let s = x + y
417 let s = x + y
@@ -576,14 +423,9 @@ filterAllInMonad str = drain $ do
576-- Nested Composition Pure lists
423-- Nested Composition Pure lists
577-------------------------------------------------------------------------------
424-------------------------------------------------------------------------------
579−-- There are several list benchmarks here for comparison with lists. It is easy
426+{-# INLINE sourceUnfoldrList #-}
580−-- and convenient to see the comparisons when they are here, otherwise we'll
427+sourceUnfoldrList :: Int -> Int -> [Int]
581−-- have to add a separate module for list benchmarks with the same names and
582−-- then add a comparison in bench.sh.
584−{-# INLINE unfoldrList #-}
585−unfoldrList :: Int -> Int -> [Int]
586−unfoldrList maxval n = List.unfoldr step n
428+sourceUnfoldrList maxval n = List.unfoldr step n
588 step cnt =
430 step cnt =
589 if cnt > n + maxval
431 if cnt > n + maxval
@@ -634,301 +476,229 @@ filterAllInNestedList str = do
634-------------------------------------------------------------------------------
476-------------------------------------------------------------------------------
636moduleName :: String
478moduleName :: String
637−moduleName = "Data.StreamK"
479+moduleName = "Data.Stream.StreamK"
639−o_1_space_generation :: Int -> Benchmark
481+o_1_space :: [Benchmark]
640−o_1_space_generation streamLen =
482+o_1_space =
483+ [ bgroup (o_1_space_prefix moduleName)
641− bgroup "generation"
484+ [ bgroup "generation"
642− [ benchFold "unfoldr" drain (unfoldr streamLen)
485+ [ benchFold "unfoldr" toNull sourceUnfoldr
643− , benchFold "unfoldrM" drain (unfoldrM streamLen)
486+ , benchFold "unfoldrM" toNull sourceUnfoldrM
644− , benchFold "repeat" drain (repeat streamLen)
487+
645− , benchFold "repeatM" drain (repeatM streamLen)
646− , benchFold "replicate" drain (replicate streamLen)
647− , benchFold "replicateM" drain (replicateM streamLen)
648− , benchFold "iterate" drain (iterate streamLen)
649− , benchFold "iterateM" drain (iterateM streamLen)
651− , benchFold "fromFoldable" drain (fromFoldable streamLen)
488+ , benchFold "fromFoldable" toNull sourceFromFoldable
652− , benchFold "fromFoldableM" drain (fromFoldableM streamLen)
489+ , benchFold "fromFoldableM" toNull sourceFromFoldableM
654 -- appends
491 -- appends
655− , benchFold "concatMapFoldableWith" drain (concatMapFoldableSerial streamLen)
492+ , benchFold "concatMapFoldableWith" toNull sourceFoldMapWith
656− , benchFold "concatMapFoldableWithM" drain (concatMapFoldableSerialM streamLen)
493+ , benchFold "concatMapFoldableWithM" toNull sourceFoldMapWithM
659−o_1_space_elimination :: Int -> Benchmark
660−o_1_space_elimination streamLen =
661− bgroup "elimination"
495+ , bgroup "elimination"
662− [ benchFold "toNull" drain (unfoldrM streamLen)
496+ [ benchFold "toNull" toNull sourceUnfoldrM
663− , benchFold "mapM_" mapM_ (unfoldrM streamLen)
497+ , benchFold "mapM_" mapM_ sourceUnfoldrM
664− , benchFold "uncons" uncons (unfoldrM streamLen)
498+ , benchFold "uncons" uncons sourceUnfoldrM
665− , benchFold "init" init (unfoldrM streamLen)
499+ , benchFold "init" init sourceUnfoldrM
666− , benchFold "foldl'" foldl' (unfoldrM streamLen)
500+ , benchFold "foldl'" foldl sourceUnfoldrM
667− , benchFold "last" last (unfoldrM streamLen)
501+ , benchFold "last" last sourceUnfoldrM
670−o_1_space_nested :: Int -> Benchmark
671−o_1_space_nested streamLen =
672− bgroup "nested"
503+ , bgroup "nested"
673− [ benchFold "drainApplicative" drainApplicative (unfoldrM streamLen2)
504+ [ benchFold "toNullAp" toNullApNested (sourceUnfoldrMN value2)
674− , benchFold "drainMonad" drainMonad (unfoldrM streamLen2)
505+ , benchFold "toNull" toNullNested (sourceUnfoldrMN value2)
675− , benchFold "drainMonad3" drainMonad3 (unfoldrM streamLen3)
506+ , benchFold "toNull3" toNullNested3 (sourceUnfoldrMN value3)
676− , benchFold "filterAllInMonad" filterAllInMonad (unfoldrM streamLen2)
507+ , benchFold "filterAllIn" filterAllInNested (sourceUnfoldrMN value2)
677− , benchFold "filterAllOutMonad" filterAllOutMonad (unfoldrM streamLen2)
508+ , benchFold "filterAllOut" filterAllOutNested (sourceUnfoldrMN value2)
678− , benchFold "drainApplicative (pure)" drainApplicative (unfoldr streamLen2)
509+ , benchFold "toNullApPure" toNullApNested (sourceUnfoldrN value2)
679− , benchFold "drainMonad (pure)" drainMonad (unfoldr streamLen2)
510+ , benchFold "toNullPure" toNullNested (sourceUnfoldrN value2)
680− , benchFold "drainMonad3 (pure)" drainMonad3 (unfoldr streamLen3)
511+ , benchFold "toNull3Pure" toNullNested3 (sourceUnfoldrN value3)
681− , benchFold "filterAllInMonad (pure)" filterAllInMonad (unfoldr streamLen2)
512+ , benchFold "filterAllInPure" filterAllInNested (sourceUnfoldrN value2)
682− , benchFold "filterAllOutMonad (pure)" filterAllOutMonad (unfoldr streamLen2)
513+ , benchFold "filterAllOutPure" filterAllOutNested (sourceUnfoldrN value2)
685− streamLen2 = round (P.fromIntegral streamLen**(1/2::P.Double)) -- double nested loop
686− streamLen3 = round (P.fromIntegral streamLen**(1/3::P.Double)) -- triple nested loop
688−o_1_space_transformation :: Int -> Benchmark
689−o_1_space_transformation streamLen =
690− bgroup "transformation"
515+ , bgroup "transformation"
691− [ benchFold "foldrS" (foldrS 1) (unfoldrM streamLen)
516+ [ benchFold "foldrS" (foldrS 1) sourceUnfoldrM
692− , benchFold "scanl'" (scanl' 1) (unfoldrM streamLen)
517+ , benchFold "scan" (scan 1) sourceUnfoldrM
693− , benchFold "map" (map 1) (unfoldrM streamLen)
518+ , benchFold "map" (map 1) sourceUnfoldrM
694− , benchFold "fmap" (fmapK 1) (unfoldrM streamLen)
519+ , benchFold "fmap" (fmapK 1) sourceUnfoldrM
695− , benchFold "mapM" (mapM 1) (unfoldrM streamLen)
520+ , benchFold "mapM" (mapM 1) sourceUnfoldrM
696− , benchFold "mapMSerial" (mapMSerial 1) (unfoldrM streamLen)
521+ , benchFold "mapMSerial" (mapMSerial 1) sourceUnfoldrM
699−o_1_space_transformationX4 :: Int -> Benchmark
700−o_1_space_transformationX4 streamLen =
701− bgroup "transformationX4"
523+ , bgroup "transformationX4"
702− [ benchFold "scanl'" (scanl' 4) (unfoldrM streamLen)
524+ [ benchFold "scan" (scan 4) sourceUnfoldrM
703− , benchFold "map" (map 4) (unfoldrM streamLen)
525+ , benchFold "map" (map 4) sourceUnfoldrM
704− , benchFold "fmap" (fmapK 4) (unfoldrM streamLen)
526+ , benchFold "fmap" (fmapK 4) sourceUnfoldrM
705− , benchFold "mapM" (mapM 4) (unfoldrM streamLen)
527+ , benchFold "mapM" (mapM 4) sourceUnfoldrM
706− , benchFold "mapMSerial" (mapMSerial 4) (unfoldrM streamLen)
528+ , benchFold "mapMSerial" (mapMSerial 4) sourceUnfoldrM
707 -- XXX this is horribly slow
529 -- XXX this is horribly slow
708− -- , benchFold "concatMap" (concatMap 4) (unfoldrM streamLen16)
530+ -- , benchFold "concatMap" (concatMap 4) (sourceUnfoldrMN value16)
711−o_1_space_concat :: Int -> Benchmark
712−o_1_space_concat streamLen =
713− bgroup "concat"
532+ , bgroup "concat"
714 [ benchIOSrc1 "concatMapPure (n of 1)"
533 [ benchIOSrc1 "concatMapPure (n of 1)"
715− (concatMapPure streamLen 1)
534+ (concatMapPure value 1)
716 , benchIOSrc1 "concatMapPure (sqrt n of sqrt n)"
535 , benchIOSrc1 "concatMapPure (sqrt n of sqrt n)"
717− (concatMapPure streamLen2 streamLen2)
536+ (concatMapPure value2 value2)
718 , benchIOSrc1 "concatMapPure (1 of n)"
537 , benchIOSrc1 "concatMapPure (1 of n)"
719− (concatMapPure 1 streamLen)
538+ (concatMapPure 1 value)
721 , benchIOSrc1 "concatMap (n of 1)"
540 , benchIOSrc1 "concatMap (n of 1)"
722− (concatMap streamLen 1)
541+ (concatMap value 1)
723 , benchIOSrc1 "concatMap (sqrt n of sqrt n)"
542 , benchIOSrc1 "concatMap (sqrt n of sqrt n)"
724− (concatMap streamLen2 streamLen2)
543+ (concatMap value2 value2)
725 , benchIOSrc1 "concatMap (1 of n)"
544 , benchIOSrc1 "concatMap (1 of n)"
726− (concatMap 1 streamLen)
545+ (concatMap 1 value)
728 , benchIOSrc1 "concatMapRepl (sqrt n of sqrt n)"
547 , benchIOSrc1 "concatMapRepl (sqrt n of sqrt n)"
729− (concatMapRepl streamLen2 streamLen2)
548+ (concatMapRepl value2 value2)
731 -- This is for comparison with concatMapFoldableWith
550 -- This is for comparison with concatMapFoldableWith
732 , benchIOSrc1 "concatMapWithId (n of 1) (fromFoldable)"
551 , benchIOSrc1 "concatMapWithId (n of 1) (fromFoldable)"
734− . S.concatMapWith S.append id
735− . sourceConcatMapId streamLen)
552+ (S.drain . S.concatMapBy S.serial id . sourceConcatMapId value)
737− , benchIOSrc1 "concatMapBy serial (n of 1)"
554+ , benchIOSrc1 "concatMapWith (n of 1)"
738− (concatMapBySerial streamLen 1)
555+ (concatStreamsWith value 1)
739− , benchIOSrc1 "concatMapBy serial (sqrt n of sqrt n)"
556+ , benchIOSrc1 "concatMapWith (sqrt n of sqrt n)"
740− (concatMapBySerial streamLen2 streamLen2)
557+ (concatStreamsWith value2 value2)
741− , benchIOSrc1 "concatMapBy serial (1 of n)"
558+ , benchIOSrc1 "concatMapWith (1 of n)"
742− (concatMapBySerial 1 streamLen)
559+ (concatStreamsWith 1 value)
743− , benchFold "sortBy" sortBy (unfoldrM streamLen)
746− streamLen2 = round (P.fromIntegral streamLen**(1/2::P.Double)) -- double nested loop
748−o_1_space_filtering :: Int -> Benchmark
749−o_1_space_filtering streamLen =
750− bgroup "filtering"
561+ , bgroup "filtering"
751− [ benchFold "filter-even" (filterEven 1) (unfoldrM streamLen)
562+ [ benchFold "filter-even" (filterEven 1) sourceUnfoldrM
752− , benchFold "filter-all-out" (filterAllOut streamLen 1) (unfoldrM streamLen)
563+ , benchFold "filter-all-out" (filterAllOut 1) sourceUnfoldrM
753− , benchFold "filter-all-in" (filterAllIn streamLen 1) (unfoldrM streamLen)
564+ , benchFold "filter-all-in" (filterAllIn 1) sourceUnfoldrM
754− , benchFold "take-all" (takeAll streamLen 1) (unfoldrM streamLen)
565+ , benchFold "take-all" (takeAll 1) sourceUnfoldrM
755− , benchFold "takeWhile-true" (takeWhileTrue streamLen 1) (unfoldrM streamLen)
566+ , benchFold "takeWhile-true" (takeWhileTrue 1) sourceUnfoldrM
756− , benchFold "drop-one" (dropOne 1) (unfoldrM streamLen)
567+ , benchFold "drop-one" (dropOne 1) sourceUnfoldrM
757− , benchFold "drop-all" (dropAll streamLen 1) (unfoldrM streamLen)
568+ , benchFold "drop-all" (dropAll 1) sourceUnfoldrM
758− , benchFold "dropWhile-true" (dropWhileTrue streamLen 1) (unfoldrM streamLen)
569+ , benchFold "dropWhile-true" (dropWhileTrue 1) sourceUnfoldrM
759− , benchFold "dropWhile-false" (dropWhileFalse 1) (unfoldrM streamLen)
570+ , benchFold "dropWhile-false" (dropWhileFalse 1) sourceUnfoldrM
762−o_1_space_filteringX4 :: Int -> Benchmark
763−o_1_space_filteringX4 streamLen =
764− bgroup "filteringX4"
572+ , bgroup "filteringX4"
765− [ benchFold "filter-even" (filterEven 4) (unfoldrM streamLen)
573+ [ benchFold "filter-even" (filterEven 4) sourceUnfoldrM
766− , benchFold "filter-all-out" (filterAllOut streamLen 4) (unfoldrM streamLen)
574+ , benchFold "filter-all-out" (filterAllOut 4) sourceUnfoldrM
767− , benchFold "filter-all-in" (filterAllIn streamLen 4) (unfoldrM streamLen)
575+ , benchFold "filter-all-in" (filterAllIn 4) sourceUnfoldrM
768− , benchFold "take-all" (takeAll streamLen 4) (unfoldrM streamLen)
576+ , benchFold "take-all" (takeAll 4) sourceUnfoldrM
769− , benchFold "takeWhile-true" (takeWhileTrue streamLen 4) (unfoldrM streamLen)
577+ , benchFold "takeWhile-true" (takeWhileTrue 4) sourceUnfoldrM
770− , benchFold "drop-one" (dropOne 4) (unfoldrM streamLen)
578+ , benchFold "drop-one" (dropOne 4) sourceUnfoldrM
771− , benchFold "drop-all" (dropAll streamLen 4) (unfoldrM streamLen)
579+ , benchFold "drop-all" (dropAll 4) sourceUnfoldrM
772− , benchFold "dropWhile-true" (dropWhileTrue streamLen 4) (unfoldrM streamLen)
580+ , benchFold "dropWhile-true" (dropWhileTrue 4) sourceUnfoldrM
773− , benchFold "dropWhile-false" (dropWhileFalse 4) (unfoldrM streamLen)
581+ , benchFold "dropWhile-false" (dropWhileFalse 4) sourceUnfoldrM
776−o_1_space_zipping :: Int -> Benchmark
777−o_1_space_zipping streamLen =
778− bgroup "zipping"
583+ , bgroup "zipping"
779− [ benchFold "zipWith" zipWith (unfoldrM streamLen)
584+ [ benchFold "zip" zip sourceUnfoldrM
780− , benchFold "zipWithM" zipWithM (unfoldrM streamLen)
783−o_1_space_mixed :: Int -> Benchmark
784−o_1_space_mixed streamLen =
785− bgroup "mixed"
586+ , bgroup "mixed"
786− [ benchFold "scan-map" (scanMap 1) (unfoldrM streamLen)
587+ [ benchFold "scan-map" (scanMap 1) sourceUnfoldrM
787− , benchFold "drop-map" (dropMap 1) (unfoldrM streamLen)
588+ , benchFold "drop-map" (dropMap 1) sourceUnfoldrM
788− , benchFold "drop-scan" (dropScan 1) (unfoldrM streamLen)
589+ , benchFold "drop-scan" (dropScan 1) sourceUnfoldrM
789− , benchFold "take-drop" (takeDrop streamLen 1) (unfoldrM streamLen)
590+ , benchFold "take-drop" (takeDrop 1) sourceUnfoldrM
790− , benchFold "take-scan" (takeScan streamLen 1) (unfoldrM streamLen)
591+ , benchFold "take-scan" (takeScan 1) sourceUnfoldrM
791− , benchFold "take-map" (takeMap streamLen 1) (unfoldrM streamLen)
592+ , benchFold "take-map" (takeMap 1) sourceUnfoldrM
792− , benchFold "filter-drop" (filterDrop streamLen 1) (unfoldrM streamLen)
593+ , benchFold "filter-drop" (filterDrop 1) sourceUnfoldrM
793− , benchFold "filter-take" (filterTake streamLen 1) (unfoldrM streamLen)
594+ , benchFold "filter-take" (filterTake 1) sourceUnfoldrM
794− , benchFold "filter-scan" (filterScan 1) (unfoldrM streamLen)
595+ , benchFold "filter-scan" (filterScan 1) sourceUnfoldrM
795− , benchFold "filter-map" (filterMap streamLen 1) (unfoldrM streamLen)
596+ , benchFold "filter-map" (filterMap 1) sourceUnfoldrM
798−o_1_space_mixedX2 :: Int -> Benchmark
799−o_1_space_mixedX2 streamLen =
800− bgroup "mixedX2"
598+ , bgroup "mixedX2"
801− [ benchFold "scan-map" (scanMap 2) (unfoldrM streamLen)
599+ [ benchFold "scan-map" (scanMap 2) sourceUnfoldrM
802− , benchFold "drop-map" (dropMap 2) (unfoldrM streamLen)
600+ , benchFold "drop-map" (dropMap 2) sourceUnfoldrM
803− , benchFold "drop-scan" (dropScan 2) (unfoldrM streamLen)
601+ , benchFold "drop-scan" (dropScan 2) sourceUnfoldrM
804− , benchFold "take-drop" (takeDrop streamLen 2) (unfoldrM streamLen)
602+ , benchFold "take-drop" (takeDrop 2) sourceUnfoldrM
805− , benchFold "take-scan" (takeScan streamLen 2) (unfoldrM streamLen)
603+ , benchFold "take-scan" (takeScan 2) sourceUnfoldrM
806− , benchFold "take-map" (takeMap streamLen 2) (unfoldrM streamLen)
604+ , benchFold "take-map" (takeMap 2) sourceUnfoldrM
807− , benchFold "filter-drop" (filterDrop streamLen 2) (unfoldrM streamLen)
605+ , benchFold "filter-drop" (filterDrop 2) sourceUnfoldrM
808− , benchFold "filter-take" (filterTake streamLen 2) (unfoldrM streamLen)
606+ , benchFold "filter-take" (filterTake 2) sourceUnfoldrM
809− , benchFold "filter-scan" (filterScan 2) (unfoldrM streamLen)
607+ , benchFold "filter-scan" (filterScan 2) sourceUnfoldrM
810− , benchFold "filter-map" (filterMap streamLen 2) (unfoldrM streamLen)
608+ , benchFold "filter-map" (filterMap 2) sourceUnfoldrM
813−o_1_space_mixedX4 :: Int -> Benchmark
814−o_1_space_mixedX4 streamLen =
815− bgroup "mixedX4"
610+ , bgroup "mixedX4"
816− [ benchFold "scan-map" (scanMap 4) (unfoldrM streamLen)
611+ [ benchFold "scan-map" (scanMap 4) sourceUnfoldrM
817− , benchFold "drop-map" (dropMap 4) (unfoldrM streamLen)
612+ , benchFold "drop-map" (dropMap 4) sourceUnfoldrM
818− , benchFold "drop-scan" (dropScan 4) (unfoldrM streamLen)
613+ , benchFold "drop-scan" (dropScan 4) sourceUnfoldrM
819− , benchFold "take-drop" (takeDrop streamLen 4) (unfoldrM streamLen)
614+ , benchFold "take-drop" (takeDrop 4) sourceUnfoldrM
820− , benchFold "take-scan" (takeScan streamLen 4) (unfoldrM streamLen)
615+ , benchFold "take-scan" (takeScan 4) sourceUnfoldrM
821− , benchFold "take-map" (takeMap streamLen 4) (unfoldrM streamLen)
616+ , benchFold "take-map" (takeMap 4) sourceUnfoldrM
822− , benchFold "filter-drop" (filterDrop streamLen 4) (unfoldrM streamLen)
617+ , benchFold "filter-drop" (filterDrop 4) sourceUnfoldrM
823− , benchFold "filter-take" (filterTake streamLen 4) (unfoldrM streamLen)
618+ , benchFold "filter-take" (filterTake 4) sourceUnfoldrM
824− , benchFold "filter-scan" (filterScan 4) (unfoldrM streamLen)
619+ , benchFold "filter-scan" (filterScan 4) sourceUnfoldrM
825− , benchFold "filter-map" (filterMap streamLen 4) (unfoldrM streamLen)
620+ , benchFold "filter-map" (filterMap 4) sourceUnfoldrM
828−o_1_space_list :: Int -> Benchmark
829−o_1_space_list streamLen =
831− [ bgroup "elimination"
832− [ benchList "last" (\xs -> [List.last xs]) (unfoldrList streamLen)
835− [ benchList "toNullAp" toNullApNestedList (unfoldrList streamLen2)
836− , benchList "toNull" toNullNestedList (unfoldrList streamLen2)
837− , benchList "toNull3" toNullNestedList3 (unfoldrList streamLen3)
838− , benchList "filterAllIn" filterAllInNestedList (unfoldrList streamLen2)
839− , benchList "filterAllOut" filterAllOutNestedList (unfoldrList streamLen2)
844− streamLen2 = round (P.fromIntegral streamLen**(1/2::P.Double)) -- double nested loop
845− streamLen3 = round (P.fromIntegral streamLen**(1/3::P.Double)) -- triple nested loop
847−o_1_space :: Int -> Benchmark
848−o_1_space streamLen =
849− bgroup (o_1_space_prefix moduleName)
850− [ o_1_space_generation streamLen
851− , o_1_space_elimination streamLen
852− , o_1_space_nested streamLen
853− , o_1_space_transformation streamLen
854− , o_1_space_transformationX4 streamLen
855− , o_1_space_concat streamLen
856− , o_1_space_filtering streamLen
857− , o_1_space_filteringX4 streamLen
858− , o_1_space_zipping streamLen
859− , o_1_space_mixed streamLen
860− , o_1_space_mixedX2 streamLen
861− , o_1_space_mixedX4 streamLen
862− , o_1_space_list streamLen
865−o_n_heap :: Int -> Benchmark
625+o_n_heap :: [Benchmark]
866−o_n_heap streamLen =
626+o_n_heap =
867− bgroup (o_n_heap_prefix moduleName)
627+ [ bgroup (o_n_heap_prefix moduleName)
868 [ bgroup "transformation"
628 [ bgroup "transformation"
869− [ benchFold "foldlS" (foldlS 1) (unfoldrM streamLen)
629+ [ benchFold "foldlS" (foldlS 1) sourceUnfoldrM
873{-# INLINE benchK #-}
634{-# INLINE benchK #-}
874benchK :: P.String -> (Int -> Stream P.IO Int) -> Benchmark
635benchK :: P.String -> (Int -> Stream P.IO Int) -> Benchmark
875−benchK name f = bench name $ nfIO $ randomRIO (1,1) >>= drain . f
636+benchK name f = bench name $ nfIO $ randomRIO (1,1) >>= toNull . f
877−o_n_stack :: Int -> Int -> Int -> Benchmark
638+o_n_stack :: [Benchmark]
878−o_n_stack streamLen iterStreamLen maxIters =
639+o_n_stack =
879− bgroup (o_n_stack_prefix moduleName)
640+ [ bgroup (o_n_stack_prefix moduleName)
880 [ bgroup "elimination"
641 [ bgroup "elimination"
881− [ benchFold "tail" tail (unfoldrM streamLen)
642+ [ benchFold "tail" tail sourceUnfoldrM
882− , benchFold "nullTail" nullTail (unfoldrM streamLen)
643+ , benchFold "nullTail" nullTail sourceUnfoldrM
883− , benchFold "headTail" headTail (unfoldrM streamLen)
644+ , benchFold "headTail" headTail sourceUnfoldrM
885 , bgroup "transformation"
646 , bgroup "transformation"
887 -- XXX why do these need so much stack
648 -- XXX why do these need so much stack
888− benchFold "intersperse" (intersperse streamLen 1) (unfoldrM streamLen2)
649+ benchFold "intersperse" (intersperse 1) (sourceUnfoldrMN value2)
889− , benchFold "interspersePure" (intersperse streamLen 1) (unfoldr streamLen2)
650+ , benchFold "interspersePure" (intersperse 1) (sourceUnfoldrN value2)
891 , bgroup "transformationX4"
652 , bgroup "transformationX4"
893− benchFold "intersperse" (intersperse streamLen 4) (unfoldrM streamLen16)
654+ benchFold "intersperse" (intersperse 4) (sourceUnfoldrMN value16)
895 , bgroup "iterated"
656 , bgroup "iterated"
896− [ benchK "mapM" (iterateMapM iterStreamLen maxIters)
657+ [ benchK "mapM" iterateMapM
897− , benchK "scan(1/10)" (iterateScan iterStreamLen maxIters)
658+ , benchK "scan(1/10)" iterateScan
898− , benchK "filterEven" (iterateFilterEven iterStreamLen maxIters)
659+ , benchK "filterEven" iterateFilterEven
899− , benchK "takeAll" (iterateTakeAll streamLen iterStreamLen maxIters)
660+ , benchK "takeAll" iterateTakeAll
900− , benchK "dropOne" (iterateDropOne iterStreamLen maxIters)
661+ , benchK "dropOne" iterateDropOne
901− , benchK "dropWhileFalse(1/10)" (iterateDropWhileFalse streamLen iterStreamLen maxIters)
662+ , benchK "dropWhileFalse(1/10)" iterateDropWhileFalse
902− , benchK "dropWhileTrue" (iterateDropWhileTrue streamLen iterStreamLen maxIters)
663+ , benchK "dropWhileTrue" iterateDropWhileTrue
906− streamLen2 = round (P.fromIntegral streamLen**(1/2::P.Double)) -- double nested loop
907− streamLen16 = round (P.fromIntegral streamLen**(1/16::P.Double)) -- triple nested loop
909−o_n_space :: Int -> Benchmark
668+o_n_space :: [Benchmark]
910−o_n_space streamLen =
669+o_n_space =
911− bgroup (o_n_space_prefix moduleName)
670+ [ bgroup (o_n_space_prefix moduleName)
912 [ bgroup "elimination"
671 [ bgroup "elimination"
913− [ benchFold "toList" toList (unfoldrM streamLen)
672+ [ benchFold "toList" toList sourceUnfoldrM
917{-# INLINE benchList #-}
677{-# INLINE benchList #-}
918benchList :: P.String -> ([Int] -> [Int]) -> (Int -> [Int]) -> Benchmark
678benchList :: P.String -> ([Int] -> [Int]) -> (Int -> [Int]) -> Benchmark
919benchList name run f = bench name $ nfIO $ randomRIO (1,1) >>= return . run . f
679benchList name run f = bench name $ nfIO $ randomRIO (1,1) >>= return . run . f
921−main :: IO ()
681+o_1_space_list :: [Benchmark]
922−main =
682+o_1_space_list =
923− defaultMain
683+ [ bgroup "list"
924− [ o_1_space streamLen
684+ [ bgroup "elimination"
925− , o_n_stack streamLen iterStreamLen maxIters
685+ [ benchList "last" (\xs -> [List.last xs]) (sourceUnfoldrList value)
926− , o_n_heap streamLen
927− , o_n_space streamLen
688+ [ benchList "toNullAp" toNullApNestedList (sourceUnfoldrList value2)
689+ , benchList "toNull" toNullNestedList (sourceUnfoldrList value2)
690+ , benchList "toNull3" toNullNestedList3 (sourceUnfoldrList value3)
691+ , benchList "filterAllIn" filterAllInNestedList (sourceUnfoldrList value2)
692+ , benchList "filterAllOut" filterAllOutNestedList (sourceUnfoldrList value2)
930− where
697+main :: IO ()
931−
698+main = defaultMain $ concat
932− streamLen = 100000
699+ [ o_1_space
933− maxIters = 10000
700+ , [bgroup (o_1_space_prefix moduleName) o_1_space_list]
934− iterStreamLen = 10
701+ , o_n_stack