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