on 3947fee help sign in
704 lines 24 kB history raw
1-- |
2-- Module : Streamly.Benchmark.Data.Stream.StreamK
3-- Copyright : (c) 2018 Composewell Technologies
4--
5-- License : BSD3
6-- Maintainer : streamly@composewell.com
8{-# LANGUAGE CPP #-}
9{-# LANGUAGE FlexibleContexts #-}
10{-# LANGUAGE ScopedTypeVariables #-}
12#ifdef __HADDOCK_VERSION__
13#undef INSPECTION
14#endif
16#ifdef INSPECTION
17{-# LANGUAGE TemplateHaskell #-}
18{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
19#endif
21module Main (main) where
23import Control.Monad (when)
24import Data.Maybe (isJust)
25import System.Random (randomRIO)
26import Prelude hiding
27 (tail, mapM_, foldl, last, map, mapM, concatMap, zip, init)
29import qualified Prelude as P
30import qualified Data.List as List
32import qualified Streamly.Internal.Data.Stream.StreamK as S
33import qualified Streamly.Internal.Data.SVar as S
35import Gauge (bench, nfIO, bgroup, Benchmark, defaultMain)
37import Streamly.Benchmark.Common
39#ifdef INSPECTION
40import Test.Inspection
41#endif
43value, value2, value3, value16, maxValue :: Int
44value = 100000
45value2 = round (P.fromIntegral value**(1/2::P.Double)) -- double nested loop
46value3 = round (P.fromIntegral value**(1/3::P.Double)) -- triple nested loop
47value16 = round (P.fromIntegral value**(1/16::P.Double)) -- triple nested loop
48maxValue = value
50-------------------------------------------------------------------------------
51-- Benchmark ops
52-------------------------------------------------------------------------------
54{-# INLINE toNull #-}
55{-# INLINE uncons #-}
56{-# INLINE nullTail #-}
57{-# INLINE headTail #-}
58{-# INLINE zip #-}
59toNull, uncons, nullTail, headTail, zip
60 :: Monad m
61 => Stream m Int -> m ()
63{-# INLINE toList #-}
64toList :: Monad m => Stream m Int -> m [Int]
65{-# INLINE foldl #-}
66foldl :: Monad m => Stream m Int -> m Int
67{-# INLINE last #-}
68last :: Monad m => Stream m Int -> m (Maybe Int)
70-------------------------------------------------------------------------------
71-- Stream generation and elimination
72-------------------------------------------------------------------------------
74type Stream m a = S.Stream m a
76{-# INLINE sourceUnfoldr #-}
77sourceUnfoldr :: Int -> Stream m Int
78sourceUnfoldr n = S.unfoldr step n
79 where
80 step cnt =
81 if cnt > n + value
82 then Nothing
83 else Just (cnt, cnt + 1)
85{-# INLINE sourceUnfoldrN #-}
86sourceUnfoldrN :: Int -> Int -> Stream m Int
87sourceUnfoldrN m n = S.unfoldr step n
88 where
89 step cnt =
90 if cnt > n + m
91 then Nothing
92 else Just (cnt, cnt + 1)
94{-# INLINE sourceUnfoldrM #-}
95sourceUnfoldrM :: S.MonadAsync m => Int -> Stream m Int
96sourceUnfoldrM n = S.unfoldrM step n
97 where
98 step cnt =
99 if cnt > n + value
100 then return Nothing
101 else return (Just (cnt, cnt + 1))
103{-# INLINE sourceUnfoldrMN #-}
104sourceUnfoldrMN :: S.MonadAsync m => Int -> Int -> Stream m Int
105sourceUnfoldrMN m n = S.unfoldrM step n
106 where
107 step cnt =
108 if cnt > n + m
109 then return Nothing
110 else return (Just (cnt, cnt + 1))
112{-# INLINE sourceFromFoldable #-}
113sourceFromFoldable :: Int -> Stream m Int
114sourceFromFoldable n = S.fromFoldable [n..n+value]
116{-# INLINE sourceFromFoldableM #-}
117sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
118sourceFromFoldableM n =
119 Prelude.foldr S.consM S.nil (Prelude.fmap return [n..n+value])
121{-# INLINABLE concatMapFoldableWith #-}
122concatMapFoldableWith :: (S.IsStream t, Foldable f)
123 => (t m b -> t m b -> t m b) -> (a -> t m b) -> f a -> t m b
124concatMapFoldableWith f g = Prelude.foldr (f . g) S.nil
126{-# INLINE sourceFoldMapWith #-}
127sourceFoldMapWith :: Int -> Stream m Int
128sourceFoldMapWith n = concatMapFoldableWith S.serial S.yield [n..n+value]
130{-# INLINE sourceFoldMapWithM #-}
131sourceFoldMapWithM :: Monad m => Int -> Stream m Int
132sourceFoldMapWithM n =
133 concatMapFoldableWith S.serial (S.yieldM . return) [n..n+value]
135-------------------------------------------------------------------------------
136-- Elimination
137-------------------------------------------------------------------------------
139{-# INLINE runStream #-}
140runStream :: Monad m => Stream m a -> m ()
141runStream = S.drain
142-- runStream = S.mapM_ (\_ -> return ())
144{-# INLINE mapM_ #-}
145mapM_ :: Monad m => Stream m a -> m ()
146mapM_ = S.mapM_ (\_ -> return ())
148toNull = runStream
149uncons s = do
150 r <- S.uncons s
151 case r of
152 Nothing -> return ()
153 Just (_, t) -> uncons t
155{-# INLINE init #-}
156init :: (Monad m, S.IsStream t) => t m a -> m ()
157init s = do
158 t <- S.init s
159 P.mapM_ S.drain t
161{-# INLINE tail #-}
162tail :: (Monad m, S.IsStream t) => t m a -> m ()
163tail s = S.tail s >>= P.mapM_ tail
165nullTail s = do
166 r <- S.null s
167 when (not r) $ S.tail s >>= P.mapM_ nullTail
169headTail s = do
170 h <- S.head s
171 when (isJust h) $ S.tail s >>= P.mapM_ headTail
173toList = S.toList
174foldl = S.foldl' (+) 0
175last = S.last
177-------------------------------------------------------------------------------
178-- Transformation
179-------------------------------------------------------------------------------
181{-# INLINE transform #-}
182transform :: Monad m => Stream m a -> m ()
183transform = runStream
185{-# INLINE composeN #-}
186composeN
187 :: Monad m
188 => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
189composeN n f =
190 case n of
191 1 -> transform . f
192 2 -> transform . f . f
193 3 -> transform . f . f . f
194 4 -> transform . f . f . f . f
195 _ -> undefined
197{-# INLINE scan #-}
198{-# INLINE map #-}
199{-# INLINE fmapK #-}
200{-# INLINE filterEven #-}
201{-# INLINE filterAllOut #-}
202{-# INLINE filterAllIn #-}
203{-# INLINE _takeOne #-}
204{-# INLINE takeAll #-}
205{-# INLINE takeWhileTrue #-}
206{-# INLINE dropOne #-}
207{-# INLINE dropAll #-}
208{-# INLINE dropWhileTrue #-}
209{-# INLINE dropWhileFalse #-}
210{-# INLINE foldrS #-}
211{-# INLINE foldlS #-}
212scan, map, fmapK, filterEven, filterAllOut,
213 filterAllIn, _takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
214 dropWhileTrue, dropWhileFalse, foldrS, foldlS
215 :: Monad m
216 => Int -> Stream m Int -> m ()
218{-# INLINE mapM #-}
219{-# INLINE mapMSerial #-}
220{-# INLINE intersperse #-}
221mapM, mapMSerial, intersperse
222 :: S.MonadAsync m => Int -> Stream m Int -> m ()
224scan n = composeN n $ S.scanl' (+) 0
225map n = composeN n $ P.fmap (+1)
226fmapK n = composeN n $ P.fmap (+1)
227mapM n = composeN n $ S.mapM return
228mapMSerial n = composeN n $ S.mapMSerial return
229filterEven n = composeN n $ S.filter even
230filterAllOut n = composeN n $ S.filter (> maxValue)
231filterAllIn n = composeN n $ S.filter (<= maxValue)
232_takeOne n = composeN n $ S.take 1
233takeAll n = composeN n $ S.take maxValue
234takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
235dropOne n = composeN n $ S.drop 1
236dropAll n = composeN n $ S.drop maxValue
237dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
238dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
239foldrS n = composeN n $ S.foldrS S.cons S.nil
240foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
241intersperse n = composeN n $ S.intersperse maxValue
243-------------------------------------------------------------------------------
244-- Iteration
245-------------------------------------------------------------------------------
247iterStreamLen, maxIters :: Int
248iterStreamLen = 10
249maxIters = 10000
251{-# INLINE iterateSource #-}
252iterateSource
253 :: S.MonadAsync m
254 => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
255iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
256 where
257 f (0 :: Int) m = g m
258 f x m = g (f (x P.- 1) m)
260{-# INLINE iterateMapM #-}
261{-# INLINE iterateScan #-}
262{-# INLINE iterateFilterEven #-}
263{-# INLINE iterateTakeAll #-}
264{-# INLINE iterateDropOne #-}
265{-# INLINE iterateDropWhileFalse #-}
266{-# INLINE iterateDropWhileTrue #-}
267iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
268 iterateDropWhileFalse, iterateDropWhileTrue
269 :: S.MonadAsync m
270 => Int -> Stream m Int
272-- this is quadratic
273iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
274iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
275 (maxIters `div` 10)
277iterateMapM = iterateSource (S.mapM return) maxIters
278iterateFilterEven = iterateSource (S.filter even) maxIters
279iterateTakeAll = iterateSource (S.take maxValue) maxIters
280iterateDropOne = iterateSource (S.drop 1) maxIters
281iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
283-------------------------------------------------------------------------------
284-- Zipping
285-------------------------------------------------------------------------------
287zip src = transform $ S.zipWith (,) src src
289-------------------------------------------------------------------------------
290-- Mixed Composition
291-------------------------------------------------------------------------------
293{-# INLINE scanMap #-}
294{-# INLINE dropMap #-}
295{-# INLINE dropScan #-}
296{-# INLINE takeDrop #-}
297{-# INLINE takeScan #-}
298{-# INLINE takeMap #-}
299{-# INLINE filterDrop #-}
300{-# INLINE filterTake #-}
301{-# INLINE filterScan #-}
302{-# INLINE filterMap #-}
303scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
304 filterTake, filterScan, filterMap
305 :: Monad m => Int -> Stream m Int -> m ()
307scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
308dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
309dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
310takeDrop n = composeN n $ S.drop 1 . S.take maxValue
311takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
312takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
313filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
314filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
315filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
316filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
318-------------------------------------------------------------------------------
319-- ConcatMap
320-------------------------------------------------------------------------------
322-- concatMap unfoldrM/unfoldrM
324{-# INLINE concatMap #-}
325concatMap :: Int -> Int -> Int -> IO ()
326concatMap outer inner n =
327 S.drain $ S.concatMap
328 (\_ -> sourceUnfoldrMN inner n)
329 (sourceUnfoldrMN outer n)
331#ifdef INSPECTION
332inspect $ hasNoTypeClasses 'concatMap
333#endif
335-- concatMap unfoldr/unfoldr
337{-# INLINE concatMapPure #-}
338concatMapPure :: Int -> Int -> Int -> IO ()
339concatMapPure outer inner n =
340 S.drain $ S.concatMap
341 (\_ -> sourceUnfoldrN inner n)
342 (sourceUnfoldrN outer n)
344#ifdef INSPECTION
345inspect $ hasNoTypeClasses 'concatMapPure
346#endif
348-- concatMap replicate/unfoldrM
350{-# INLINE concatMapRepl #-}
351concatMapRepl :: Int -> Int -> Int -> IO ()
352concatMapRepl outer inner n =
353 S.drain $ S.concatMap (S.replicate inner) (sourceUnfoldrMN outer n)
355#ifdef INSPECTION
356inspect $ hasNoTypeClasses 'concatMapRepl
357#endif
359-- concatMapWith
361{-# INLINE sourceConcatMapId #-}
362sourceConcatMapId :: Monad m
363 => Int -> Int -> Stream m (Stream m Int)
364sourceConcatMapId val n =
365 S.fromFoldable $ fmap (S.yieldM . return) [n..n+val]
367{-# INLINE concatStreamsWith #-}
368concatStreamsWith :: Int -> Int -> Int -> IO ()
369concatStreamsWith outer inner n =
370 S.drain $ S.concatMapBy S.serial
371 (sourceUnfoldrMN inner)
372 (sourceUnfoldrMN outer n)
374-------------------------------------------------------------------------------
375-- Nested Composition
376-------------------------------------------------------------------------------
378{-# INLINE toNullApNested #-}
379toNullApNested :: Monad m => Stream m Int -> m ()
380toNullApNested s = runStream $ do
381 (+) <$> s <*> s
383{-# INLINE toNullNested #-}
384toNullNested :: Monad m => Stream m Int -> m ()
385toNullNested s = runStream $ do
386 x <- s
387 y <- s
388 return $ x + y
390{-# INLINE toNullNested3 #-}
391toNullNested3 :: Monad m => Stream m Int -> m ()
392toNullNested3 s = runStream $ do
393 x <- s
394 y <- s
395 z <- s
396 return $ x + y + z
398{-# INLINE filterAllOutNested #-}
399filterAllOutNested
400 :: Monad m
401 => Stream m Int -> m ()
402filterAllOutNested str = runStream $ do
403 x <- str
404 y <- str
405 let s = x + y
406 if s < 0
407 then return s
408 else S.nil
410{-# INLINE filterAllInNested #-}
411filterAllInNested
412 :: Monad m
413 => Stream m Int -> m ()
414filterAllInNested str = runStream $ do
415 x <- str
416 y <- str
417 let s = x + y
418 if s > 0
419 then return s
420 else S.nil
422-------------------------------------------------------------------------------
423-- Nested Composition Pure lists
424-------------------------------------------------------------------------------
426{-# INLINE sourceUnfoldrList #-}
427sourceUnfoldrList :: Int -> Int -> [Int]
428sourceUnfoldrList maxval n = List.unfoldr step n
429 where
430 step cnt =
431 if cnt > n + maxval
432 then Nothing
433 else Just (cnt, cnt + 1)
435{-# INLINE toNullApNestedList #-}
436toNullApNestedList :: [Int] -> [Int]
437toNullApNestedList s = (+) <$> s <*> s
439{-# INLINE toNullNestedList #-}
440toNullNestedList :: [Int] -> [Int]
441toNullNestedList s = do
442 x <- s
443 y <- s
444 return $ x + y
446{-# INLINE toNullNestedList3 #-}
447toNullNestedList3 :: [Int] -> [Int]
448toNullNestedList3 s = do
449 x <- s
450 y <- s
451 z <- s
452 return $ x + y + z
454{-# INLINE filterAllOutNestedList #-}
455filterAllOutNestedList :: [Int] -> [Int]
456filterAllOutNestedList str = do
457 x <- str
458 y <- str
459 let s = x + y
460 if s < 0
461 then return s
462 else []
464{-# INLINE filterAllInNestedList #-}
465filterAllInNestedList :: [Int] -> [Int]
466filterAllInNestedList str = do
467 x <- str
468 y <- str
469 let s = x + y
470 if s > 0
471 then return s
472 else []
474-------------------------------------------------------------------------------
475-- Benchmarks
476-------------------------------------------------------------------------------
478moduleName :: String
479moduleName = "Data.Stream.StreamK"
481o_1_space :: [Benchmark]
482o_1_space =
483 [ bgroup (o_1_space_prefix moduleName)
484 [ bgroup "generation"
485 [ benchFold "unfoldr" toNull sourceUnfoldr
486 , benchFold "unfoldrM" toNull sourceUnfoldrM
488 , benchFold "fromFoldable" toNull sourceFromFoldable
489 , benchFold "fromFoldableM" toNull sourceFromFoldableM
491 -- appends
492 , benchFold "concatMapFoldableWith" toNull sourceFoldMapWith
493 , benchFold "concatMapFoldableWithM" toNull sourceFoldMapWithM
494 ]
495 , bgroup "elimination"
496 [ benchFold "toNull" toNull sourceUnfoldrM
497 , benchFold "mapM_" mapM_ sourceUnfoldrM
498 , benchFold "uncons" uncons sourceUnfoldrM
499 , benchFold "init" init sourceUnfoldrM
500 , benchFold "foldl'" foldl sourceUnfoldrM
501 , benchFold "last" last sourceUnfoldrM
502 ]
503 , bgroup "nested"
504 [ benchFold "toNullAp" toNullApNested (sourceUnfoldrMN value2)
505 , benchFold "toNull" toNullNested (sourceUnfoldrMN value2)
506 , benchFold "toNull3" toNullNested3 (sourceUnfoldrMN value3)
507 , benchFold "filterAllIn" filterAllInNested (sourceUnfoldrMN value2)
508 , benchFold "filterAllOut" filterAllOutNested (sourceUnfoldrMN value2)
509 , benchFold "toNullApPure" toNullApNested (sourceUnfoldrN value2)
510 , benchFold "toNullPure" toNullNested (sourceUnfoldrN value2)
511 , benchFold "toNull3Pure" toNullNested3 (sourceUnfoldrN value3)
512 , benchFold "filterAllInPure" filterAllInNested (sourceUnfoldrN value2)
513 , benchFold "filterAllOutPure" filterAllOutNested (sourceUnfoldrN value2)
514 ]
515 , bgroup "transformation"
516 [ benchFold "foldrS" (foldrS 1) sourceUnfoldrM
517 , benchFold "scan" (scan 1) sourceUnfoldrM
518 , benchFold "map" (map 1) sourceUnfoldrM
519 , benchFold "fmap" (fmapK 1) sourceUnfoldrM
520 , benchFold "mapM" (mapM 1) sourceUnfoldrM
521 , benchFold "mapMSerial" (mapMSerial 1) sourceUnfoldrM
522 ]
523 , bgroup "transformationX4"
524 [ benchFold "scan" (scan 4) sourceUnfoldrM
525 , benchFold "map" (map 4) sourceUnfoldrM
526 , benchFold "fmap" (fmapK 4) sourceUnfoldrM
527 , benchFold "mapM" (mapM 4) sourceUnfoldrM
528 , benchFold "mapMSerial" (mapMSerial 4) sourceUnfoldrM
529 -- XXX this is horribly slow
530 -- , benchFold "concatMap" (concatMap 4) (sourceUnfoldrMN value16)
531 ]
532 , bgroup "concat"
533 [ benchIOSrc1 "concatMapPure (n of 1)"
534 (concatMapPure value 1)
535 , benchIOSrc1 "concatMapPure (sqrt n of sqrt n)"
536 (concatMapPure value2 value2)
537 , benchIOSrc1 "concatMapPure (1 of n)"
538 (concatMapPure 1 value)
540 , benchIOSrc1 "concatMap (n of 1)"
541 (concatMap value 1)
542 , benchIOSrc1 "concatMap (sqrt n of sqrt n)"
543 (concatMap value2 value2)
544 , benchIOSrc1 "concatMap (1 of n)"
545 (concatMap 1 value)
547 , benchIOSrc1 "concatMapRepl (sqrt n of sqrt n)"
548 (concatMapRepl value2 value2)
550 -- This is for comparison with concatMapFoldableWith
551 , benchIOSrc1 "concatMapWithId (n of 1) (fromFoldable)"
552 (S.drain . S.concatMapBy S.serial id . sourceConcatMapId value)
554 , benchIOSrc1 "concatMapWith (n of 1)"
555 (concatStreamsWith value 1)
556 , benchIOSrc1 "concatMapWith (sqrt n of sqrt n)"
557 (concatStreamsWith value2 value2)
558 , benchIOSrc1 "concatMapWith (1 of n)"
559 (concatStreamsWith 1 value)
560 ]
561 , bgroup "filtering"
562 [ benchFold "filter-even" (filterEven 1) sourceUnfoldrM
563 , benchFold "filter-all-out" (filterAllOut 1) sourceUnfoldrM
564 , benchFold "filter-all-in" (filterAllIn 1) sourceUnfoldrM
565 , benchFold "take-all" (takeAll 1) sourceUnfoldrM
566 , benchFold "takeWhile-true" (takeWhileTrue 1) sourceUnfoldrM
567 , benchFold "drop-one" (dropOne 1) sourceUnfoldrM
568 , benchFold "drop-all" (dropAll 1) sourceUnfoldrM
569 , benchFold "dropWhile-true" (dropWhileTrue 1) sourceUnfoldrM
570 , benchFold "dropWhile-false" (dropWhileFalse 1) sourceUnfoldrM
571 ]
572 , bgroup "filteringX4"
573 [ benchFold "filter-even" (filterEven 4) sourceUnfoldrM
574 , benchFold "filter-all-out" (filterAllOut 4) sourceUnfoldrM
575 , benchFold "filter-all-in" (filterAllIn 4) sourceUnfoldrM
576 , benchFold "take-all" (takeAll 4) sourceUnfoldrM
577 , benchFold "takeWhile-true" (takeWhileTrue 4) sourceUnfoldrM
578 , benchFold "drop-one" (dropOne 4) sourceUnfoldrM
579 , benchFold "drop-all" (dropAll 4) sourceUnfoldrM
580 , benchFold "dropWhile-true" (dropWhileTrue 4) sourceUnfoldrM
581 , benchFold "dropWhile-false" (dropWhileFalse 4) sourceUnfoldrM
582 ]
583 , bgroup "zipping"
584 [ benchFold "zip" zip sourceUnfoldrM
585 ]
586 , bgroup "mixed"
587 [ benchFold "scan-map" (scanMap 1) sourceUnfoldrM
588 , benchFold "drop-map" (dropMap 1) sourceUnfoldrM
589 , benchFold "drop-scan" (dropScan 1) sourceUnfoldrM
590 , benchFold "take-drop" (takeDrop 1) sourceUnfoldrM
591 , benchFold "take-scan" (takeScan 1) sourceUnfoldrM
592 , benchFold "take-map" (takeMap 1) sourceUnfoldrM
593 , benchFold "filter-drop" (filterDrop 1) sourceUnfoldrM
594 , benchFold "filter-take" (filterTake 1) sourceUnfoldrM
595 , benchFold "filter-scan" (filterScan 1) sourceUnfoldrM
596 , benchFold "filter-map" (filterMap 1) sourceUnfoldrM
597 ]
598 , bgroup "mixedX2"
599 [ benchFold "scan-map" (scanMap 2) sourceUnfoldrM
600 , benchFold "drop-map" (dropMap 2) sourceUnfoldrM
601 , benchFold "drop-scan" (dropScan 2) sourceUnfoldrM
602 , benchFold "take-drop" (takeDrop 2) sourceUnfoldrM
603 , benchFold "take-scan" (takeScan 2) sourceUnfoldrM
604 , benchFold "take-map" (takeMap 2) sourceUnfoldrM
605 , benchFold "filter-drop" (filterDrop 2) sourceUnfoldrM
606 , benchFold "filter-take" (filterTake 2) sourceUnfoldrM
607 , benchFold "filter-scan" (filterScan 2) sourceUnfoldrM
608 , benchFold "filter-map" (filterMap 2) sourceUnfoldrM
609 ]
610 , bgroup "mixedX4"
611 [ benchFold "scan-map" (scanMap 4) sourceUnfoldrM
612 , benchFold "drop-map" (dropMap 4) sourceUnfoldrM
613 , benchFold "drop-scan" (dropScan 4) sourceUnfoldrM
614 , benchFold "take-drop" (takeDrop 4) sourceUnfoldrM
615 , benchFold "take-scan" (takeScan 4) sourceUnfoldrM
616 , benchFold "take-map" (takeMap 4) sourceUnfoldrM
617 , benchFold "filter-drop" (filterDrop 4) sourceUnfoldrM
618 , benchFold "filter-take" (filterTake 4) sourceUnfoldrM
619 , benchFold "filter-scan" (filterScan 4) sourceUnfoldrM
620 , benchFold "filter-map" (filterMap 4) sourceUnfoldrM
621 ]
622 ]
623 ]
625o_n_heap :: [Benchmark]
626o_n_heap =
627 [ bgroup (o_n_heap_prefix moduleName)
628 [ bgroup "transformation"
629 [ benchFold "foldlS" (foldlS 1) sourceUnfoldrM
630 ]
631 ]
632 ]
634{-# INLINE benchK #-}
635benchK :: P.String -> (Int -> Stream P.IO Int) -> Benchmark
636benchK name f = bench name $ nfIO $ randomRIO (1,1) >>= toNull . f
638o_n_stack :: [Benchmark]
639o_n_stack =
640 [ bgroup (o_n_stack_prefix moduleName)
641 [ bgroup "elimination"
642 [ benchFold "tail" tail sourceUnfoldrM
643 , benchFold "nullTail" nullTail sourceUnfoldrM
644 , benchFold "headTail" headTail sourceUnfoldrM
645 ]
646 , bgroup "transformation"
647 [
648 -- XXX why do these need so much stack
649 benchFold "intersperse" (intersperse 1) (sourceUnfoldrMN value2)
650 , benchFold "interspersePure" (intersperse 1) (sourceUnfoldrN value2)
651 ]
652 , bgroup "transformationX4"
653 [
654 benchFold "intersperse" (intersperse 4) (sourceUnfoldrMN value16)
655 ]
656 , bgroup "iterated"
657 [ benchK "mapM" iterateMapM
658 , benchK "scan(1/10)" iterateScan
659 , benchK "filterEven" iterateFilterEven
660 , benchK "takeAll" iterateTakeAll
661 , benchK "dropOne" iterateDropOne
662 , benchK "dropWhileFalse(1/10)" iterateDropWhileFalse
663 , benchK "dropWhileTrue" iterateDropWhileTrue
664 ]
665 ]
666 ]
668o_n_space :: [Benchmark]
669o_n_space =
670 [ bgroup (o_n_space_prefix moduleName)
671 [ bgroup "elimination"
672 [ benchFold "toList" toList sourceUnfoldrM
673 ]
674 ]
675 ]
677{-# INLINE benchList #-}
678benchList :: P.String -> ([Int] -> [Int]) -> (Int -> [Int]) -> Benchmark
679benchList name run f = bench name $ nfIO $ randomRIO (1,1) >>= return . run . f
681o_1_space_list :: [Benchmark]
682o_1_space_list =
683 [ bgroup "list"
684 [ bgroup "elimination"
685 [ benchList "last" (\xs -> [List.last xs]) (sourceUnfoldrList value)
686 ]
687 , bgroup "nested"
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)
693 ]
694 ]
695 ]
697main :: IO ()
698main = defaultMain $ concat
699 [ o_1_space
700 , [bgroup (o_1_space_prefix moduleName) o_1_space_list]
701 , o_n_stack
702 , o_n_heap
703 , o_n_space
704 ]