on master help sign in
Move Prelude.Serial benchmarks to Data.Stream
commit8fbc085ef472dd70b34b82f138c19d9da284558a authorRanjeet Kumar Ranjan <ranjeetr@composewell.com> dateMon 1 Aug 2022, 18:41 (4 years ago) parentd2aaef0
18 files changed+715−300
.github/workflows/regression-check.yml+1−1 .hlint.yaml+7−6 benchmark/Streamly/Benchmark/Prelude/Serial.hs → benchmark/Streamly/Benchmark/Data/Stream.hs+20−14 benchmark/Streamly/Benchmark/Data/Stream/Common.hs+70 benchmark/Streamly/Benchmark/Prelude/Serial/Elimination.hs → benchmark/Streamly/Benchmark/Data/Stream/Eliminate.hs+88−59 benchmark/Streamly/Benchmark/Prelude/Serial/Exceptions.hs → benchmark/Streamly/Benchmark/Data/Stream/Exceptions.hs+63−31 benchmark/Streamly/Benchmark/Prelude/Serial/Generation.hs → benchmark/Streamly/Benchmark/Data/Stream/Generate.hs+60−11 benchmark/Streamly/Benchmark/Prelude/Serial/Lift.hs → benchmark/Streamly/Benchmark/Data/Stream/Lift.hs+58−18 benchmark/Streamly/Benchmark/Prelude/Serial/NestedFold.hs → benchmark/Streamly/Benchmark/Data/Stream/NestedFold.hs+2−2 benchmark/Streamly/Benchmark/Prelude/Serial/NestedStream.hs → benchmark/Streamly/Benchmark/Data/Stream/NestedStream.hs+3−3 benchmark/Streamly/Benchmark/Data/Stream/Reduce.hs+124 benchmark/Streamly/Benchmark/Prelude/Serial/Split.hs → benchmark/Streamly/Benchmark/Data/Stream/Split.hs+2−2 benchmark/Streamly/Benchmark/Prelude/Serial/Transformation.hs → benchmark/Streamly/Benchmark/Data/Stream/Transformation.hs+166−98 benchmark/bench-runner/Main.hs+9−9 benchmark/streamly-benchmarks.cabal+38−25 hie.yaml+2−18 streamly.cabal−1 targets/Targets.hs+2−2
.github/workflows/regression-check.yml+1−1
@@ -25,6 +25,7 @@ jobs:
2525 Data.Parser.ParserD
2626 Data.Parser.ParserK
2727 Data.SmallArray
28+ Data.Stream
2829 Data.Stream.StreamD
2930 Data.Stream.StreamDK
3031 Data.Stream.StreamK:6
@@ -33,7 +34,6 @@ jobs:
3334 Prelude.Ahead
3435 Prelude.Async:12
3536 Prelude.Parallel
36− Prelude.Serial
3737 Prelude.WAsync:6
3838 Prelude.WSerial
3939 Prelude.ZipAsync
.hlint.yaml+7−6
@@ -26,12 +26,13 @@
2626- ignore: {name: "Use fmap"}
2727
2828# Warnings ignored in specific places
29−- ignore: {name: "Use ++", within: Serial.Transformation}
30−- ignore: {name: "Use mapM", within: Serial.Transformation}
31−- ignore: {name: "Use traverse", within: Serial.Transformation}
32−
33−- ignore: {name: "Redundant <*", within: Serial.NestedStream}
34−- ignore: {name: "Use ++", within: Serial.NestedStream}
29+- ignore: {name: "Use ++", within: Stream.Transformation}
30+- ignore: {name: "Use mapM", within: Stream.Transformation}
31+- ignore: {name: "Use traverse", within: Stream.Transformation}
32+- ignore: {name: "Redundant <*", within: Stream.NestedStream}
33+- ignore: {name: "Use ++", within: Stream.NestedStream}
34+- ignore: {name: "Use ++", within: Stream.Split}
35+- ignore: {name: "Redundant bracket", within: Stream.Split}
3536- ignore: {name: "Use isDigit", within: Streamly.Internal.Unicode.Char.Parser}
3637
3738# Specify additional command line arguments
benchmark/Streamly/Benchmark/Prelude/Serial.hs → benchmark/Streamly/Benchmark/Data/Stream.hsrenamed+20−14
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Serial
2+-- Module : Data.Stream
33-- Copyright : (c) 2018 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -13,19 +13,22 @@ module Main (main) where
1313
1414import Streamly.Benchmark.Common.Handle (mkHandleBenchEnv)
1515
16−import qualified Serial.Elimination as Elimination
17−import qualified Serial.Exceptions as Exceptions
18−import qualified Serial.Generation as Generation
19−import qualified Serial.NestedStream as NestedStream
20−import qualified Serial.Split as Split
21−import qualified Serial.Transformation as Transformation
22−import qualified Serial.NestedFold as NestedFold
23−import qualified Serial.Lift as Lift
16+import qualified Stream.Eliminate as Elimination
17+import qualified Stream.Exceptions as Exceptions
18+import qualified Stream.Generate as Generation
19+import qualified Stream.Lift as Lift
20+import qualified Stream.Reduce as Reduction
21+import qualified Stream.Transformation as Transformation
22+#ifdef USE_PRELUDE
23+import qualified Stream.NestedFold as NestedFold
24+import qualified Stream.NestedStream as NestedStream
25+import qualified Stream.Split as Split
26+#endif
2427
2528import Streamly.Benchmark.Common
2629
2730moduleName :: String
28−moduleName = "Prelude.Serial"
31+moduleName = "Data.Stream"
2932
3033-------------------------------------------------------------------------------
3134-- Main
@@ -42,12 +45,15 @@ main = do
4245 where
4346
4447 allBenchmarks env size = Prelude.concat
45− [ Generation.benchmarks moduleName size
46− , Elimination.benchmarks moduleName size
48+ [ Elimination.benchmarks moduleName size
4749 , Exceptions.benchmarks moduleName env size
48− , Split.benchmarks moduleName env
50+ , Generation.benchmarks moduleName size
51+ , Lift.benchmarks moduleName size
52+ , Reduction.benchmarks moduleName size
4953 , Transformation.benchmarks moduleName size
54+#ifdef USE_PRELUDE
5055 , NestedFold.benchmarks moduleName size
51− , Lift.benchmarks moduleName size
5256 , NestedStream.benchmarks moduleName size
57+ , Split.benchmarks moduleName env
58+#endif
5359 ]
benchmark/Streamly/Benchmark/Data/Stream/Common.hsnew file+70
@@ -0,0 +1,70 @@
1+-- |
2+-- Module : Stream.Common
3+-- Copyright : (c) 2018 Composewell Technologies
4+-- License : BSD-3-Clause
5+-- Maintainer : streamly@composewell.com
6+
7+module Stream.Common
8+ ( sourceUnfoldr
9+ , sourceUnfoldrM
10+ , sourceUnfoldrAction
11+ , benchIOSink
12+ , benchIOSrc
13+ )
14+where
15+
16+import Streamly.Internal.Data.Stream (Stream, unfold)
17+import qualified Streamly.Internal.Data.Fold as Fold
18+import qualified Streamly.Internal.Data.Stream as Stream
19+import qualified Streamly.Internal.Data.Unfold as UF
20+import Control.DeepSeq (NFData)
21+import Gauge
22+import Prelude hiding (mapM)
23+import System.Random (randomRIO)
24+
25+{-# INLINE toNull #-}
26+toNull :: Monad m => Stream m a -> m ()
27+toNull = Stream.fold Fold.drain
28+
29+{-# INLINE sourceUnfoldrM #-}
30+sourceUnfoldrM :: Monad m => Int -> Int -> Stream m Int
31+sourceUnfoldrM count start = unfold (UF.unfoldrM step) start
32+ where
33+ step cnt =
34+ if cnt > start + count
35+ then return Nothing
36+ else return (Just (cnt, cnt + 1))
37+
38+{-# INLINE sourceUnfoldr #-}
39+sourceUnfoldr :: Monad m => Int -> Int -> Stream m Int
40+sourceUnfoldr count start = unfold (UF.unfoldr step) start
41+ where
42+ step cnt =
43+ if cnt > start + count
44+ then Nothing
45+ else Just (cnt, cnt + 1)
46+
47+{-# INLINE sourceUnfoldrAction #-}
48+sourceUnfoldrAction :: (Monad m1, Monad m) => Int -> Int -> Stream m (m1 Int)
49+sourceUnfoldrAction value n = unfold (UF.unfoldr step) n
50+ where
51+ step cnt =
52+ if cnt > n + value
53+ then Nothing
54+ else Just (return cnt, cnt + 1)
55+
56+{-# INLINE benchIOSink #-}
57+benchIOSink
58+ :: (NFData b)
59+ => Int -> String -> (Stream IO Int -> IO b) -> Benchmark
60+benchIOSink value name f =
61+ bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldrM value
62+
63+-- | Takes a source, and uses it with a default drain/fold method.
64+{-# INLINE benchIOSrc #-}
65+benchIOSrc
66+ :: String
67+ -> (Int -> Stream IO a)
68+ -> Benchmark
69+benchIOSrc name f =
70+ bench name $ nfIO $ randomRIO (1,1) >>= toNull . f
benchmark/Streamly/Benchmark/Prelude/Serial/Elimination.hs → benchmark/Streamly/Benchmark/Data/Stream/Eliminate.hsrenamed+88−59
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Serial.Elimination
2+-- Module : Stream.Eliminate
33-- Copyright : (c) 2018 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -18,7 +18,7 @@
1818{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
1919#endif
2020
21−module Serial.Elimination (benchmarks) where
21+module Stream.Eliminate (benchmarks) where
2222
2323import Control.DeepSeq (NFData(..))
2424import Data.Functor.Identity (Identity, runIdentity)
@@ -33,22 +33,39 @@ import Test.Inspection
3333
3434import qualified Streamly.Internal.Data.Stream.StreamD as D
3535#endif
36−
36+import qualified Streamly.Internal.Data.Fold as Fold
37+#ifdef USE_PRELUDE
3738import qualified Streamly.Prelude as S
39+import qualified Streamly.Internal.Data.Stream.IsStream as S
3840import qualified Streamly.Internal.Data.Stream.IsStream as Internal
41+#else
42+import qualified Streamly.Internal.Data.Stream as S
43+#endif
3944
4045import Gauge
41−import Streamly.Prelude (SerialT, IsStream, fromSerial)
42−import Streamly.Benchmark.Common
46+import Streamly.Internal.Data.Stream.Serial (SerialT)
47+#ifdef USE_PRELUDE
48+import Streamly.Prelude (fromSerial)
4349import Streamly.Benchmark.Prelude
50+#else
51+import Stream.Common
52+ ( sourceUnfoldr
53+ , sourceUnfoldrM
54+ , sourceUnfoldrAction
55+ , benchIOSink
56+ )
57+#endif
58+import Streamly.Benchmark.Common
59+
4460import Prelude hiding (length, sum, or, and, any, all, notElem, elem, (!!),
4561 lookup, repeat, minimum, maximum, product, last, mapM_, init)
4662import qualified Prelude
4763
64+#ifdef USE_PRELUDE
4865{-# INLINE repeat #-}
4966repeat :: (Monad m, S.IsStream t) => Int -> Int -> t m Int
5067repeat count = S.take count . S.repeat
51−
68+#endif
5269-------------------------------------------------------------------------------
5370-- Elimination
5471-------------------------------------------------------------------------------
@@ -60,76 +77,76 @@ repeat count = S.take count . S.repeat
6077{-# INLINE foldableFoldl' #-}
6178foldableFoldl' :: Int -> Int -> Int
6279foldableFoldl' value n =
63− F.foldl' (+) 0 (sourceUnfoldr value n :: S.SerialT Identity Int)
80+ F.foldl' (+) 0 (sourceUnfoldr value n :: SerialT Identity Int)
6481
6582{-# INLINE foldableFoldrElem #-}
6683foldableFoldrElem :: Int -> Int -> Bool
6784foldableFoldrElem value n =
6885 F.foldr (\x xs -> x == value || xs)
6986 False
70− (sourceUnfoldr value n :: S.SerialT Identity Int)
87+ (sourceUnfoldr value n :: SerialT Identity Int)
7188
7289{-# INLINE foldableSum #-}
7390foldableSum :: Int -> Int -> Int
7491foldableSum value n =
75− Prelude.sum (sourceUnfoldr value n :: S.SerialT Identity Int)
92+ Prelude.sum (sourceUnfoldr value n :: SerialT Identity Int)
7693
7794{-# INLINE foldableProduct #-}
7895foldableProduct :: Int -> Int -> Int
7996foldableProduct value n =
80− Prelude.product (sourceUnfoldr value n :: S.SerialT Identity Int)
97+ Prelude.product (sourceUnfoldr value n :: SerialT Identity Int)
8198
8299{-# INLINE _foldableNull #-}
83100_foldableNull :: Int -> Int -> Bool
84101_foldableNull value n =
85− Prelude.null (sourceUnfoldr value n :: S.SerialT Identity Int)
102+ Prelude.null (sourceUnfoldr value n :: SerialT Identity Int)
86103
87104{-# INLINE foldableElem #-}
88105foldableElem :: Int -> Int -> Bool
89106foldableElem value n =
90− value `Prelude.elem` (sourceUnfoldr value n :: S.SerialT Identity Int)
107+ value `Prelude.elem` (sourceUnfoldr value n :: SerialT Identity Int)
91108
92109{-# INLINE foldableNotElem #-}
93110foldableNotElem :: Int -> Int -> Bool
94111foldableNotElem value n =
95− value `Prelude.notElem` (sourceUnfoldr value n :: S.SerialT Identity Int)
112+ value `Prelude.notElem` (sourceUnfoldr value n :: SerialT Identity Int)
96113
97114{-# INLINE foldableFind #-}
98115foldableFind :: Int -> Int -> Maybe Int
99116foldableFind value n =
100− F.find (== (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
117+ F.find (== (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
101118
102119{-# INLINE foldableAll #-}
103120foldableAll :: Int -> Int -> Bool
104121foldableAll value n =
105− Prelude.all (<= (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
122+ Prelude.all (<= (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
106123
107124{-# INLINE foldableAny #-}
108125foldableAny :: Int -> Int -> Bool
109126foldableAny value n =
110− Prelude.any (> (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
127+ Prelude.any (> (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
111128
112129{-# INLINE foldableAnd #-}
113130foldableAnd :: Int -> Int -> Bool
114131foldableAnd value n =
115− Prelude.and $ S.map
116− (<= (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
132+ Prelude.and $ fmap
133+ (<= (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
117134
118135{-# INLINE foldableOr #-}
119136foldableOr :: Int -> Int -> Bool
120137foldableOr value n =
121− Prelude.or $ S.map
122− (> (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
138+ Prelude.or $ fmap
139+ (> (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
123140
124141{-# INLINE foldableLength #-}
125142foldableLength :: Int -> Int -> Int
126143foldableLength value n =
127− Prelude.length (sourceUnfoldr value n :: S.SerialT Identity Int)
144+ Prelude.length (sourceUnfoldr value n :: SerialT Identity Int)
128145
129146{-# INLINE foldableMin #-}
130147foldableMin :: Int -> Int -> Int
131148foldableMin value n =
132− Prelude.minimum (sourceUnfoldr value n :: S.SerialT Identity Int)
149+ Prelude.minimum (sourceUnfoldr value n :: SerialT Identity Int)
133150
134151{-# INLINE ordInstanceMin #-}
135152ordInstanceMin :: SerialT Identity Int -> SerialT Identity Int
@@ -138,12 +155,12 @@ ordInstanceMin src = min src src
138155{-# INLINE foldableMax #-}
139156foldableMax :: Int -> Int -> Int
140157foldableMax value n =
141− Prelude.maximum (sourceUnfoldr value n :: S.SerialT Identity Int)
158+ Prelude.maximum (sourceUnfoldr value n :: SerialT Identity Int)
142159
143160{-# INLINE foldableMinBy #-}
144161foldableMinBy :: Int -> Int -> Int
145162foldableMinBy value n =
146− F.minimumBy compare (sourceUnfoldr value n :: S.SerialT Identity Int)
163+ F.minimumBy compare (sourceUnfoldr value n :: SerialT Identity Int)
147164
148165{-# INLINE foldableListMinBy #-}
149166foldableListMinBy :: Int -> Int -> Int
@@ -152,27 +169,27 @@ foldableListMinBy value n = F.minimumBy compare [1..value+n]
152169{-# INLINE foldableMaxBy #-}
153170foldableMaxBy :: Int -> Int -> Int
154171foldableMaxBy value n =
155− F.maximumBy compare (sourceUnfoldr value n :: S.SerialT Identity Int)
172+ F.maximumBy compare (sourceUnfoldr value n :: SerialT Identity Int)
156173
157174{-# INLINE foldableToList #-}
158175foldableToList :: Int -> Int -> [Int]
159176foldableToList value n =
160− F.toList (sourceUnfoldr value n :: S.SerialT Identity Int)
177+ F.toList (sourceUnfoldr value n :: SerialT Identity Int)
161178
162179{-# INLINE foldableMapM_ #-}
163180foldableMapM_ :: Monad m => Int -> Int -> m ()
164181foldableMapM_ value n =
165− F.mapM_ (\_ -> return ()) (sourceUnfoldr value n :: S.SerialT Identity Int)
182+ F.mapM_ (\_ -> return ()) (sourceUnfoldr value n :: SerialT Identity Int)
166183
167184{-# INLINE foldableSequence_ #-}
168185foldableSequence_ :: Int -> Int -> IO ()
169186foldableSequence_ value n =
170− F.sequence_ (sourceUnfoldrAction value n :: S.SerialT Identity (IO Int))
187+ F.sequence_ (sourceUnfoldrAction value n :: SerialT Identity (IO Int))
171188
172189{-# INLINE _foldableMsum #-}
173190_foldableMsum :: Int -> Int -> IO Int
174191_foldableMsum value n =
175− F.msum (sourceUnfoldrAction value n :: S.SerialT Identity (IO Int))
192+ F.msum (sourceUnfoldrAction value n :: SerialT Identity (IO Int))
176193
177194{-# INLINE showInstance #-}
178195showInstance :: SerialT Identity Int -> String
@@ -240,8 +257,8 @@ benchPureSink value name = benchPure name (sourceUnfoldr value)
240257
241258{-# INLINE benchHoistSink #-}
242259benchHoistSink
243− :: (IsStream t, NFData b)
244− => Int -> String -> (t Identity Int -> IO b) -> Benchmark
260+ :: (NFData b)
261+ => Int -> String -> (SerialT Identity Int -> IO b) -> Benchmark
245262benchHoistSink value name f =
246263 bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldr value
247264
@@ -249,8 +266,8 @@ benchHoistSink value name f =
249266-- we can't use it as it requires MonadAsync constraint.
250267{-# INLINE benchIdentitySink #-}
251268benchIdentitySink
252− :: (IsStream t, NFData b)
253− => Int -> String -> (t Identity Int -> Identity b) -> Benchmark
269+ :: (NFData b)
270+ => Int -> String -> (SerialT Identity Int -> Identity b) -> Benchmark
254271benchIdentitySink value name f = bench name $ nf (f . sourceUnfoldr value) 1
255272
256273-------------------------------------------------------------------------------
@@ -264,7 +281,7 @@ uncons s = do
264281 case r of
265282 Nothing -> return ()
266283 Just (_, t) -> uncons t
267−
284+#ifdef USE_PRELUDE
268285{-# INLINE init #-}
269286init :: Monad m => SerialT m a -> m ()
270287init s = S.init s >>= Prelude.mapM_ S.drain
@@ -272,6 +289,7 @@ init s = S.init s >>= Prelude.mapM_ S.drain
272289{-# INLINE mapM_ #-}
273290mapM_ :: Monad m => SerialT m Int -> m ()
274291mapM_ = S.mapM_ (\_ -> return ())
292+#endif
275293
276294{-# INLINE foldrMElem #-}
277295foldrMElem :: Monad m => Int -> SerialT m Int -> m Bool
@@ -290,7 +308,7 @@ foldrToStream = S.foldr S.cons S.nil
290308{-# INLINE foldrMBuild #-}
291309foldrMBuild :: Monad m => SerialT m Int -> m [Int]
292310foldrMBuild = S.foldrM (\x xs -> (x :) <$> xs) (return [])
293−
311+#ifdef USE_PRELUDE
294312{-# INLINE foldl'Reduce #-}
295313foldl'Reduce :: Monad m => SerialT m Int -> m Int
296314foldl'Reduce = S.foldl' (+) 0
@@ -398,40 +416,47 @@ drainWhile = S.drainWhile (const True)
398416{-# INLINE lookup #-}
399417lookup :: Monad m => Int -> SerialT m Int -> m (Maybe Int)
400418lookup val = S.lookup val . S.map (\x -> (x, x))
401−
419+#endif
402420o_1_space_elimination_folds :: Int -> [Benchmark]
403421o_1_space_elimination_folds value =
404422 [ bgroup "elimination"
405423 -- Basic folds
406− [ bgroup "reduce"
424+ [
425+#ifdef USE_PRELUDE
426+ bgroup "reduce"
407427 [ bgroup
408428 "IO"
409429 [ benchIOSink value "foldl'" foldl'Reduce
410430 , benchIOSink value "foldl1'" foldl1'Reduce
411431 , benchIOSink value "foldlM'" foldlM'Reduce
412432 ]
433+
413434 , bgroup
414435 "Identity"
415436 [ benchIdentitySink value "foldl'" foldl'Reduce
416437 , benchIdentitySink value "foldl1'" foldl1'Reduce
417438 , benchIdentitySink value "foldlM'" foldlM'Reduce
418439 ]
419− ]
420− , bgroup "build"
440+ ] ,
441+#endif
442+ bgroup "build"
421443 [ bgroup "IO"
422444 [ benchIOSink value "foldrMElem" (foldrMElem value)
423445 ]
424446 , bgroup "Identity"
425447 [ benchIdentitySink value "foldrMElem" (foldrMElem value)
426− , benchIdentitySink value "foldrToStreamLength"
427− (S.length . runIdentity . foldrToStream)
428448 , benchPureSink value "foldrMToListLength"
429449 (Prelude.length . runIdentity . foldrMBuild)
450+ , benchIdentitySink value "foldrToStreamLength"
451+ (S.fold Fold.length . runIdentity . foldrToStream)
430452 ]
431453 ]
432454
433455 -- deconstruction
434456 , benchIOSink value "uncons" uncons
457+ , benchHoistSink value "length . generally"
458+ (S.fold Fold.length . S.generally)
459+#ifdef USE_PRELUDE
435460 , benchIOSink value "init" init
436461
437462 -- draining
@@ -442,19 +467,18 @@ o_1_space_elimination_folds value =
442467 , benchIOSink value "mapM_" mapM_
443468
444469 -- this is too fast, causes all benchmarks reported in ns
445− -- , benchIOSink value "head" head
470+ --, benchIOSink value "head" head
446471 , benchIOSink value "last" last
447472 , benchIOSink value "length" length
448− , benchHoistSink value "length . generally"
449− (length . Internal.generally)
450473 , benchIOSink value "sum" sum
451474 , benchIOSink value "product" product
452475 , benchIOSink value "maximumBy" maximumBy
453476 , benchIOSink value "maximum" maximum
454477 , benchIOSink value "minimumBy" minimumBy
455478 , benchIOSink value "minimum" minimum
456−
479+#ifdef USE_PRELUDE
457480 , bench "the" $ nfIO $ randomRIO (1,1) >>= the . repeat value
481+#endif
458482 , benchIOSink value "find" (find value)
459483 , benchIOSink value "findM" (findM value)
460484 -- , benchIOSink value "lookupFirst" (lookup 1)
@@ -463,13 +487,14 @@ o_1_space_elimination_folds value =
463487 , benchIOSink value "findIndex" (findIndex value)
464488 , benchIOSink value "elemIndex" (elemIndex value)
465489 -- this is too fast, causes all benchmarks reported in ns
466− -- , benchIOSink value "null" S.null
490+ -- , benchIOSink value "null" S.null
467491 , benchIOSink value "elem" (elem value)
468492 , benchIOSink value "notElem" (notElem value)
469493 , benchIOSink value "all" (all value)
470494 , benchIOSink value "any" (any value)
471495 , benchIOSink value "and" (and value)
472496 , benchIOSink value "or" (or value)
497+#endif
473498
474499 -- length is used to check for foldr/build fusion
475500 , benchPureSink value "length . IsList.toList" (Prelude.length . GHC.toList)
@@ -479,7 +504,7 @@ o_1_space_elimination_folds value =
479504-------------------------------------------------------------------------------
480505-- Buffered Transformations by fold
481506-------------------------------------------------------------------------------
482−
507+#ifdef USE_PRELUDE
483508{-# INLINE foldl'Build #-}
484509foldl'Build :: Monad m => SerialT m Int -> m [Int]
485510foldl'Build = S.foldl' (flip (:)) []
@@ -499,6 +524,7 @@ o_n_heap_elimination_foldl value =
499524 , benchIdentitySink value "foldlM'/build/Identity" foldlM'Build
500525 ]
501526 ]
527+#endif
502528
503529-- For comparisons
504530{-# INLINE showInstanceList #-}
@@ -533,7 +559,7 @@ o_n_space_elimination_foldr value =
533559 , benchIOSink value "foldrM/reduce/IO (sum)" foldrMReduce
534560 ]
535561 ]
536−
562+#ifdef USE_PRELUDE
537563o_n_heap_elimination_toList :: Int -> [Benchmark]
538564o_n_heap_elimination_toList value =
539565 [ bgroup "toList"
@@ -553,7 +579,7 @@ o_n_space_elimination_toList value =
553579 (Internal.toStream :: (SerialT IO Int -> IO (SerialT Identity Int)))
554580 ]
555581 ]
556−
582+#endif
557583-------------------------------------------------------------------------------
558584-- Multi-stream folds
559585-------------------------------------------------------------------------------
@@ -673,14 +699,17 @@ benchmarks moduleName size =
673699 , o_1_space_elimination_multi_stream_pure size
674700 , o_1_space_elimination_multi_stream size
675701 ]
676− , bgroup (o_n_heap_prefix moduleName) $ concat
677− [ o_n_heap_elimination_foldl size
678− , o_n_heap_elimination_toList size
679− , o_n_heap_elimination_buffered size
680− ]
681− , bgroup (o_n_space_prefix moduleName) $ concat
682− [ o_n_space_elimination_foldable size
683− , o_n_space_elimination_toList size
684− , o_n_space_elimination_foldr size
685− ]
702+
703+ , bgroup (o_n_heap_prefix moduleName) $
704+ o_n_heap_elimination_buffered size
705+#ifdef USE_PRELUDE
706+ ++ o_n_heap_elimination_foldl size
707+ ++ o_n_heap_elimination_toList size
708+#endif
709+ , bgroup (o_n_space_prefix moduleName) $
710+ o_n_space_elimination_foldable size
711+#ifdef USE_PRELUDE
712+ ++ o_n_space_elimination_toList size
713+#endif
714+ ++ o_n_space_elimination_foldr size
686715 ]
benchmark/Streamly/Benchmark/Prelude/Serial/Exceptions.hs → benchmark/Streamly/Benchmark/Data/Stream/Exceptions.hsrenamed+63−31
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Streamly.Benchmark.Prelude.Serial.Exceptions
2+-- Module : Stream.Exceptions
33-- Copyright : (c) 2019 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -18,7 +18,7 @@
1818{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
1919#endif
2020
21−module Serial.Exceptions (benchmarks) where
21+module Stream.Exceptions (benchmarks) where
2222
2323import Control.Exception (SomeException, Exception, throwIO)
2424import System.IO (Handle, hClose, hPutChar)
@@ -29,10 +29,18 @@ import qualified Data.Map.Strict as Map
2929import qualified Streamly.FileSystem.Handle as FH
3030import qualified Streamly.Internal.Data.Unfold as IUF
3131import qualified Streamly.Internal.FileSystem.Handle as IFH
32−import qualified Streamly.Internal.Data.Stream.IsStream as IP
32+#ifdef USE_PRELUDE
33+import qualified Streamly.Internal.Data.Stream.IsStream as Stream
3334import qualified Streamly.Prelude as S
35+#else
36+import qualified Streamly.Internal.Data.Stream as Stream
37+import qualified Streamly.Internal.Data.Stream as S
38+import qualified Streamly.Internal.Data.Fold as Fold
39+import qualified Streamly.Internal.Data.Unfold as Unfold
40+#endif
3441
3542import Gauge hiding (env)
43+import Streamly.Internal.Data.Stream.Serial (SerialT)
3644import Prelude hiding (last, length)
3745import Streamly.Benchmark.Common
3846import Streamly.Benchmark.Common.Handle
@@ -47,6 +55,28 @@ import qualified Streamly.Internal.Data.Stream.StreamD as D
4755-- stream exceptions
4856-------------------------------------------------------------------------------
4957
58+drain :: SerialT IO a -> IO ()
59+#ifdef USE_PRELUDE
60+drain = Stream.drain
61+#else
62+drain = Stream.fold Fold.drain
63+#endif
64+
65+enumerateFromTo :: Int -> Int -> SerialT IO Int
66+#ifdef USE_PRELUDE
67+enumerateFromTo length from = S.enumerateFromTo from (from + length)
68+#else
69+enumerateFromTo length from = Stream.unfold Unfold.enumerateFromTo (from, from + length)
70+#endif
71+
72+sourceRef :: (Num b) => Int -> Int -> Ref.IORef b -> SerialT IO b
73+#ifdef USE_PRELUDE
74+sourceRef length from ref = S.replicateM (from + length)
75+#else
76+sourceRef length from ref = Stream.unfold (Unfold.replicateM (from + length))
77+#endif
78+ $ Ref.modifyIORef' ref (+ 1) >> Ref.readIORef ref
79+
5080data BenchException
5181 = BenchException1
5282 | BenchException2
@@ -56,37 +86,40 @@ instance Exception BenchException
5686
5787retryNoneSimple :: Int -> Int -> IO ()
5888retryNoneSimple length from =
59− IP.drain
60− $ IP.retry (Map.singleton BenchException1 length) (const S.nil) source
89+ drain
90+ $ Stream.retry
91+ (Map.singleton BenchException1 length)
92+ (const S.nil)
93+ source
6194
6295 where
6396
64− source = S.enumerateFromTo from (from + length)
97+ source = enumerateFromTo length from
6598
6699retryNone :: Int -> Int -> IO ()
67100retryNone length from = do
68101 ref <- Ref.newIORef (0 :: Int)
69− IP.drain
70− $ IP.retry (Map.singleton BenchException1 length) (const S.nil)
102+ drain
103+ $ Stream.retry (Map.singleton BenchException1 length) (const S.nil)
71104 $ source ref
72105
73106 where
74107
75− source ref =
76− IP.replicateM (from + length)
77− $ Ref.modifyIORef' ref (+ 1) >> Ref.readIORef ref
108+ source = sourceRef length from
109+
78110
79111retryAll :: Int -> Int -> IO ()
80112retryAll length from = do
81113 ref <- Ref.newIORef 0
82− IP.drain
83− $ IP.retry (Map.singleton BenchException1 (length + from)) (const S.nil)
114+ drain
115+ $ Stream.retry
116+ (Map.singleton BenchException1 (length + from)) (const S.nil)
84117 $ source ref
85118
86119 where
87120
88121 source ref =
89− IP.fromEffect
122+ Stream.fromEffect
90123 $ do
91124 Ref.modifyIORef' ref (+ 1)
92125 val <- Ref.readIORef ref
@@ -96,13 +129,13 @@ retryAll length from = do
96129
97130retryUnknown :: Int -> Int -> IO ()
98131retryUnknown length from = do
99− IP.drain
100− $ IP.retry (Map.singleton BenchException1 length) (const source)
132+ drain
133+ $ Stream.retry (Map.singleton BenchException1 length) (const source)
101134 $ throwIO BenchException2 `S.before` S.nil
102135
103136 where
104137
105− source = S.enumerateFromTo from (from + length)
138+ source = enumerateFromTo length from
106139
107140
108141o_1_space_serial_exceptions :: Int -> [Benchmark]
@@ -124,7 +157,7 @@ o_1_space_serial_exceptions length =
124157readWriteOnExceptionStream :: Handle -> Handle -> IO ()
125158readWriteOnExceptionStream inh devNull =
126159 let readEx = S.onException (hClose inh) (S.unfold FH.read inh)
127− in S.fold (FH.write devNull) $ readEx
160+ in S.fold (FH.write devNull) readEx
128161
129162#ifdef INSPECTION
130163inspect $ hasNoTypeClasses 'readWriteOnExceptionStream
@@ -135,7 +168,7 @@ readWriteHandleExceptionStream :: Handle -> Handle -> IO ()
135168readWriteHandleExceptionStream inh devNull =
136169 let handler (_e :: SomeException) = S.fromEffect (hClose inh >> return 10)
137170 readEx = S.handle handler (S.unfold FH.read inh)
138− in S.fold (FH.write devNull) $ readEx
171+ in S.fold (FH.write devNull) readEx
139172
140173#ifdef INSPECTION
141174inspect $ hasNoTypeClasses 'readWriteHandleExceptionStream
@@ -144,7 +177,7 @@ inspect $ hasNoTypeClasses 'readWriteHandleExceptionStream
144177-- | Send the file contents to /dev/null with exception handling
145178readWriteFinally_Stream :: Handle -> Handle -> IO ()
146179readWriteFinally_Stream inh devNull =
147− let readEx = IP.finally_ (hClose inh) (S.unfold FH.read inh)
180+ let readEx = Stream.finally_ (hClose inh) (S.unfold FH.read inh)
148181 in S.fold (FH.write devNull) readEx
149182
150183#ifdef INSPECTION
@@ -159,9 +192,9 @@ readWriteFinallyStream inh devNull =
159192-- | Send the file contents to /dev/null with exception handling
160193fromToBytesBracket_Stream :: Handle -> Handle -> IO ()
161194fromToBytesBracket_Stream inh devNull =
162− let readEx = IP.bracket_ (return ()) (\_ -> hClose inh)
195+ let readEx = Stream.bracket_ (return ()) (\_ -> hClose inh)
163196 (\_ -> IFH.getBytes inh)
164− in IFH.putBytes devNull $ readEx
197+ in IFH.putBytes devNull readEx
165198
166199#ifdef INSPECTION
167200inspect $ hasNoTypeClasses 'fromToBytesBracket_Stream
@@ -171,13 +204,13 @@ fromToBytesBracketStream :: Handle -> Handle -> IO ()
171204fromToBytesBracketStream inh devNull =
172205 let readEx = S.bracket (return ()) (\_ -> hClose inh)
173206 (\_ -> IFH.getBytes inh)
174− in IFH.putBytes devNull $ readEx
207+ in IFH.putBytes devNull readEx
175208
176209readWriteBeforeAfterStream :: Handle -> Handle -> IO ()
177210readWriteBeforeAfterStream inh devNull =
178211 let readEx =
179− IP.after (hClose inh)
180− $ IP.before (hPutChar devNull 'A') (S.unfold FH.read inh)
212+ Stream.after (hClose inh)
213+ $ Stream.before (hPutChar devNull 'A') (S.unfold FH.read inh)
181214 in S.fold (FH.write devNull) readEx
182215
183216#ifdef INSPECTION
@@ -186,7 +219,7 @@ inspect $ 'readWriteBeforeAfterStream `hasNoType` ''D.Step
186219
187220readWriteAfterStream :: Handle -> Handle -> IO ()
188221readWriteAfterStream inh devNull =
189− let readEx = IP.after (hClose inh) (S.unfold FH.read inh)
222+ let readEx = Stream.after (hClose inh) (S.unfold FH.read inh)
190223 in S.fold (FH.write devNull) readEx
191224
192225#ifdef INSPECTION
@@ -195,7 +228,7 @@ inspect $ 'readWriteAfterStream `hasNoType` ''D.Step
195228
196229readWriteAfter_Stream :: Handle -> Handle -> IO ()
197230readWriteAfter_Stream inh devNull =
198− let readEx = IP.after_ (hClose inh) (S.unfold FH.read inh)
231+ let readEx = Stream.after_ (hClose inh) (S.unfold FH.read inh)
199232 in S.fold (FH.write devNull) readEx
200233
201234#ifdef INSPECTION
@@ -277,11 +310,11 @@ o_1_space_copy_exceptions_readChunks env =
277310-- | Send the file contents to /dev/null with exception handling
278311toChunksBracket_ :: Handle -> Handle -> IO ()
279312toChunksBracket_ inh devNull =
280− let readEx = IP.bracket_
313+ let readEx = Stream.bracket_
281314 (return ())
282315 (\_ -> hClose inh)
283316 (\_ -> IFH.getChunks inh)
284− in S.fold (IFH.writeChunks devNull) $ readEx
317+ in S.fold (IFH.writeChunks devNull) readEx
285318
286319#ifdef INSPECTION
287320inspect $ hasNoTypeClasses 'toChunksBracket_
@@ -293,7 +326,7 @@ toChunksBracket inh devNull =
293326 (return ())
294327 (\_ -> hClose inh)
295328 (\_ -> IFH.getChunks inh)
296− in S.fold (IFH.writeChunks devNull) $ readEx
329+ in S.fold (IFH.writeChunks devNull) readEx
297330
298331o_1_space_copy_exceptions_toChunks :: BenchEnv -> [Benchmark]
299332o_1_space_copy_exceptions_toChunks env =
@@ -305,7 +338,6 @@ o_1_space_copy_exceptions_toChunks env =
305338 ]
306339 ]
307340
308−
309341benchmarks :: String -> BenchEnv -> Int -> [Benchmark]
310342benchmarks moduleName env size =
311343 [ bgroup (o_1_space_prefix moduleName) $ concat
benchmark/Streamly/Benchmark/Prelude/Serial/Generation.hs → benchmark/Streamly/Benchmark/Data/Stream/Generate.hsrenamed+60−11
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Serial.Generation
2+-- Module : Stream.Generate
33-- Copyright : (c) 2018 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -9,19 +9,29 @@
99{-# LANGUAGE ScopedTypeVariables #-}
1010{-# LANGUAGE RankNTypes #-}
1111
12−module Serial.Generation (benchmarks) where
12+module Stream.Generate (benchmarks) where
1313
1414import Data.Functor.Identity (Identity)
1515
16−import qualified Prelude
16+#ifdef USE_PRELUDE
1717import qualified GHC.Exts as GHC
18−
19−import qualified Streamly.Prelude as S
18+import qualified Streamly.Prelude as S
19+import qualified Prelude
20+#endif
21+import qualified Streamly.Internal.Data.Stream as Stream
22+import qualified Streamly.Internal.Data.Unfold as Unfold
2023
2124import Gauge
22−import Streamly.Prelude (SerialT, fromSerial, MonadAsync)
2325import Streamly.Benchmark.Common
26+import Streamly.Internal.Data.Stream.Serial (SerialT)
27+#ifdef USE_PRELUDE
2428import Streamly.Benchmark.Prelude
29+import Streamly.Prelude (fromSerial, MonadAsync)
30+#endif
31+import qualified Stream.Common as SC
32+
33+import System.IO.Unsafe (unsafeInterleaveIO)
34+
2535import Prelude hiding (repeat, replicate, iterate)
2636
2737-------------------------------------------------------------------------------
@@ -31,7 +41,7 @@ import Prelude hiding (repeat, replicate, iterate)
3141-------------------------------------------------------------------------------
3242-- fromList
3343-------------------------------------------------------------------------------
34−
44+#ifdef USE_PRELUDE
3545{-# INLINE sourceIsList #-}
3646sourceIsList :: Int -> Int -> SerialT Identity Int
3747sourceIsList value n = GHC.fromList [n..n+value]
@@ -39,6 +49,7 @@ sourceIsList value n = GHC.fromList [n..n+value]
3949{-# INLINE sourceIsString #-}
4050sourceIsString :: Int -> Int -> SerialT Identity Char
4151sourceIsString value n = GHC.fromString (Prelude.replicate (n + value) 'a')
52+#endif
4253
4354{-# INLINE readInstance #-}
4455readInstance :: String -> SerialT Identity Int
@@ -57,6 +68,7 @@ readInstanceList str =
5768 [(x,"")] -> x
5869 _ -> error "readInstance: no parse"
5970
71+#ifdef USE_PRELUDE
6072{-# INLINE repeat #-}
6173repeat :: (Monad m, S.IsStream t) => Int -> Int -> t m Int
6274repeat count = S.take count . S.repeat
@@ -115,8 +127,8 @@ fromIndices value n = S.take value $ S.fromIndices (+ n)
115127fromIndicesM :: (MonadAsync m, S.IsStream t) => Int -> Int -> t m Int
116128fromIndicesM value n = S.take value $ S.fromIndicesM (return <$> (+ n))
117129
118−o_1_space_generation :: Int -> [Benchmark]
119−o_1_space_generation value =
130+o_1_space_generation_prel :: Int -> [Benchmark]
131+o_1_space_generation_prel value =
120132 [ bgroup "generation"
121133 [ benchIOSrc fromSerial "unfoldr" (sourceUnfoldr value)
122134 , benchIOSrc fromSerial "unfoldrM" (sourceUnfoldrM value)
@@ -147,10 +159,42 @@ o_1_space_generation value =
147159 -- These essentially test cons and consM
148160 , benchIOSrc fromSerial "fromFoldable" (sourceFromFoldable value)
149161 , benchIOSrc fromSerial "fromFoldableM" (sourceFromFoldableM value)
150−
151162 , benchIOSrc fromSerial "absTimes" $ absTimes value
152163 ]
153164 ]
165+#endif
166+
167+{-# INLINE mfixUnfold #-}
168+mfixUnfold :: Int -> Int -> SerialT IO (Int, Int)
169+mfixUnfold count start = Stream.mfix f
170+ where
171+ f action = do
172+ let incr n act = fmap ((+n) . snd) $ unsafeInterleaveIO act
173+ x <- Stream.unfold Unfold.fromListM [incr 1 action, incr 2 action]
174+ y <- SC.sourceUnfoldr count start
175+ return (x, y)
176+
177+{-# INLINE fromFoldable #-}
178+fromFoldable :: Int -> Int -> SerialT m Int
179+fromFoldable count start =
180+ Stream.fromFoldable (Prelude.enumFromTo count start)
181+
182+{-# INLINE fromFoldableM #-}
183+fromFoldableM :: Monad m => Int -> Int -> SerialT m Int
184+fromFoldableM count start =
185+ Stream.fromFoldableM (fmap return (Prelude.enumFromTo count start))
186+
187+o_1_space_generation :: Int -> [Benchmark]
188+o_1_space_generation value =
189+ [ bgroup "generation"
190+ [ SC.benchIOSrc "unfold" (SC.sourceUnfoldr value)
191+ , SC.benchIOSrc "fromFoldable" (fromFoldable value)
192+ , SC.benchIOSrc "fromFoldableM" (fromFoldableM value)
193+ , SC.benchIOSrc "mfix_10" (mfixUnfold 10)
194+ , SC.benchIOSrc "mfix_100" (mfixUnfold 100)
195+ , SC.benchIOSrc "mfix_1000" (mfixUnfold 1000)
196+ ]
197+ ]
154198
155199o_n_heap_generation :: Int -> [Benchmark]
156200o_n_heap_generation value =
@@ -174,6 +218,11 @@ o_n_heap_generation value =
174218--
175219benchmarks :: String -> Int -> [Benchmark]
176220benchmarks moduleName size =
177− [ bgroup (o_1_space_prefix moduleName) (o_1_space_generation size)
221+ [
222+#ifdef USE_PRELUDE
223+ bgroup (o_1_space_prefix moduleName) (o_1_space_generation_prel size)
224+ ,
225+#endif
226+ bgroup (o_1_space_prefix moduleName) (o_1_space_generation size)
178227 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_generation size)
179228 ]
benchmark/Streamly/Benchmark/Prelude/Serial/Lift.hs → benchmark/Streamly/Benchmark/Data/Stream/Lift.hsrenamed+58−18
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Serial.Lift
2+-- Module : Stream.Lift
33-- Copyright : (c) 2018 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -9,29 +9,38 @@
99{-# LANGUAGE ScopedTypeVariables #-}
1010{-# LANGUAGE RankNTypes #-}
1111
12−module Serial.Lift (benchmarks) where
12+module Stream.Lift (benchmarks) where
1313
14+#ifdef USE_PRELUDE
15+import Control.Monad.Trans.Class (lift)
1416import Control.Monad.State.Strict (StateT, get, put, MonadState)
17+import Streamly.Prelude (fromSerial)
18+import Streamly.Benchmark.Prelude
1519import qualified Control.Monad.State.Strict as State
16−import Control.Monad.Trans.Class (lift)
17−
18−import qualified Streamly.Prelude as S
20+import qualified Streamly.Prelude as Stream
1921import qualified Streamly.Internal.Data.Stream.IsStream as Internal
22+#else
23+import Control.DeepSeq (NFData(..))
24+import Data.Functor.Identity (Identity)
25+import Stream.Common (sourceUnfoldr, sourceUnfoldrM, benchIOSrc)
26+import System.Random (randomRIO)
27+import qualified Streamly.Internal.Data.Stream as Stream
28+#endif
2029
2130import Gauge
22−import Streamly.Prelude (SerialT, fromSerial)
31+import Streamly.Internal.Data.Stream.Serial (SerialT)
2332import Streamly.Benchmark.Common
24−import Streamly.Benchmark.Prelude
33+
2534import Prelude hiding (reverse, tail)
2635
2736-------------------------------------------------------------------------------
2837-- Monad transformation (hoisting etc.)
2938-------------------------------------------------------------------------------
30−
39+#ifdef USE_PRELUDE
3140{-# INLINE sourceUnfoldrState #-}
32−sourceUnfoldrState :: (S.IsStream t, S.MonadAsync m)
41+sourceUnfoldrState :: (Stream.IsStream t, Stream.MonadAsync m)
3342 => Int -> Int -> t (StateT Int m) Int
34−sourceUnfoldrState value n = S.unfoldrM step n
43+sourceUnfoldrState value n = Stream.unfoldrM step n
3544 where
3645 step cnt =
3746 if cnt > n + value
@@ -42,12 +51,12 @@ sourceUnfoldrState value n = S.unfoldrM step n
4251 return (Just (s, cnt + 1))
4352
4453{-# INLINE evalStateT #-}
45−evalStateT :: S.MonadAsync m => Int -> Int -> SerialT m Int
54+evalStateT :: Stream.MonadAsync m => Int -> Int -> SerialT m Int
4655evalStateT value n =
4756 Internal.evalStateT (return 0) (sourceUnfoldrState value n)
4857
4958{-# INLINE withState #-}
50−withState :: S.MonadAsync m => Int -> Int -> SerialT m Int
59+withState :: Stream.MonadAsync m => Int -> Int -> SerialT m Int
5160withState value n =
5261 Internal.evalStateT
5362 (return (0 :: Int)) (Internal.liftInner (sourceUnfoldrM value n))
@@ -62,7 +71,7 @@ o_1_space_hoisting value =
6271
6372{-# INLINE iterateStateIO #-}
6473iterateStateIO ::
65− (S.MonadAsync m)
74+ (Stream.MonadAsync m)
6675 => Int
6776 -> StateT Int m Int
6877iterateStateIO n = do
@@ -86,7 +95,7 @@ iterateStateT n = do
8695{-# INLINE iterateState #-}
8796{-# SPECIALIZE iterateState :: Int -> SerialT (StateT Int IO) Int #-}
8897iterateState ::
89− (S.MonadAsync m, MonadState Int m)
98+ (Stream.MonadAsync m, MonadState Int m)
9099 => Int
91100 -> SerialT m Int
92101iterateState n = do
@@ -103,12 +112,38 @@ o_n_heap_transformer value =
103112 [ benchIO "StateT Int IO (n times) (baseline)" $ \n ->
104113 State.evalStateT (iterateStateIO n) value
105114 , benchIO "SerialT (StateT Int IO) (n times)" $ \n ->
106− State.evalStateT (S.drain (iterateStateT n)) value
115+ State.evalStateT (Stream.drain (iterateStateT n)) value
107116 , benchIO "MonadState Int m => SerialT m Int" $ \n ->
108− State.evalStateT (S.drain (iterateState n)) value
117+ State.evalStateT (Stream.drain (iterateState n)) value
109118 ]
110119 ]
111−
120+#else
121+{-# INLINE benchHoistSink #-}
122+benchHoistSink
123+ :: (NFData b)
124+ => Int -> String -> (SerialT Identity Int -> IO b) -> Benchmark
125+benchHoistSink value name f =
126+ bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldr value
127+
128+-- XXX We should be using sourceUnfoldrM for fair comparison with IO monad, but
129+-- we can't use it as it requires MonadAsync constraint.
130+
131+{-# INLINE liftInner #-}
132+liftInner :: Monad m => Int -> Int -> SerialT m Int
133+liftInner value n =
134+ Stream.evalStateT
135+ (return (0 :: Int)) (Stream.liftInner (sourceUnfoldrM value n))
136+
137+o_1_space_generation :: Int -> [Benchmark]
138+o_1_space_generation value =
139+ [ bgroup "lift"
140+ [ benchHoistSink value "length . generally"
141+ ((\(_ :: SerialT IO Int) -> return 8 :: IO Int) . Stream.generally)
142+
143+ , benchIOSrc "liftInner/evalStateT" (liftInner value)
144+ ]
145+ ]
146+#endif
112147-------------------------------------------------------------------------------
113148-- Main
114149-------------------------------------------------------------------------------
@@ -118,6 +153,11 @@ o_n_heap_transformer value =
118153--
119154benchmarks :: String -> Int -> [Benchmark]
120155benchmarks moduleName size =
121− [ bgroup (o_1_space_prefix moduleName) (o_1_space_hoisting size)
156+ [
157+#ifdef USE_PRELUDE
158+ bgroup (o_1_space_prefix moduleName) (o_1_space_hoisting size)
122159 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_transformer size)
160+#else
161+ bgroup (o_1_space_prefix moduleName) (o_1_space_generation size)
162+#endif
123163 ]
benchmark/Streamly/Benchmark/Prelude/Serial/NestedFold.hs → benchmark/Streamly/Benchmark/Data/Stream/NestedFold.hsrenamed+2−2
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Serial.NestedFold
2+-- Module : Stream.NestedFold
33-- Copyright : (c) 2018 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -11,7 +11,7 @@
1111{-# LANGUAGE DeriveGeneric #-}
1212{-# LANGUAGE RankNTypes #-}
1313
14−module Serial.NestedFold (benchmarks) where
14+module Stream.NestedFold (benchmarks) where
1515
1616import Control.DeepSeq (NFData(..))
1717import Control.Monad (when)
benchmark/Streamly/Benchmark/Prelude/Serial/NestedStream.hs → benchmark/Streamly/Benchmark/Data/Stream/NestedStream.hsrenamed+3−3
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Serial.NestedStream
2+-- Module : Stream.NestedStream
33-- Copyright : (c) 2018 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -18,7 +18,7 @@
1818{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
1919#endif
2020
21−module Serial.NestedStream (benchmarks) where
21+module Stream.NestedStream (benchmarks) where
2222
2323import Control.Monad.Trans.Class (lift)
2424
@@ -356,7 +356,7 @@ o_n_space_applicative value =
356356 [ benchIOSrc fromSerial "(*>) (n times)" $
357357 iterateSingleton ((*>) . pure) value
358358 , benchIOSrc fromSerial "(<*) (n times)" $
359− iterateSingleton (\x xs -> xs <* pure x) value
359+ iterateSingleton (\x xs -> xs <* pure x) value
360360 , benchIOSrc fromSerial "(<*>) (n times)" $
361361 iterateSingleton (\x xs -> pure (+ x) <*> xs) value
362362 , benchIOSrc fromSerial "liftA2 (n times)" $
benchmark/Streamly/Benchmark/Data/Stream/Reduce.hsnew file+124
@@ -0,0 +1,124 @@
1+-- |
2+-- Module : Stream.Reduce
3+-- Copyright : (c) 2018 Composewell Technologies
4+-- License : BSD-3-Clause
5+-- Maintainer : streamly@composewell.com
6+
7+{-# LANGUAGE CPP #-}
8+{-# LANGUAGE FlexibleContexts #-}
9+{-# LANGUAGE ScopedTypeVariables #-}
10+{-# LANGUAGE RankNTypes #-}
11+
12+module Stream.Reduce (benchmarks) where
13+
14+import Control.Monad.Catch (MonadCatch)
15+import Data.Monoid (Sum(Sum), getSum)
16+import Stream.Common (benchIOSink)
17+import Streamly.Benchmark.Common (o_1_space_prefix)
18+import Streamly.Internal.Data.Stream (Stream)
19+
20+import qualified Streamly.Internal.Data.Stream as Stream
21+import qualified Streamly.Internal.Data.Parser as PR
22+import qualified Streamly.Internal.Data.Parser.ParserD as ParserD
23+
24+import Prelude hiding (length, sum, or, and, any, all, notElem, elem, (!!),
25+ lookup, repeat, minimum, maximum, product, last, mapM_, init)
26+
27+import Gauge
28+
29+import qualified Streamly.Data.Fold as FL
30+import qualified Streamly.Internal.Data.Refold.Type as Refold
31+import Control.Monad.IO.Class (MonadIO)
32+
33+{-# INLINE foldMany #-}
34+foldMany :: Monad m => Stream m Int -> m ()
35+foldMany =
36+ Stream.fold FL.drain
37+ . fmap getSum
38+ . Stream.foldMany (FL.take 2 FL.mconcat)
39+ . fmap Sum
40+
41+{-# INLINE foldManyPost #-}
42+foldManyPost :: Monad m => Stream m Int -> m ()
43+foldManyPost =
44+ Stream.fold FL.drain
45+ . fmap getSum
46+ . Stream.foldManyPost (FL.take 2 FL.mconcat)
47+ . fmap Sum
48+
49+{-# INLINE refoldMany #-}
50+refoldMany :: Monad m => Stream m Int -> m ()
51+refoldMany =
52+ Stream.fold FL.drain
53+ . fmap getSum
54+ . Stream.refoldMany (Refold.take 2 Refold.sconcat) (return mempty)
55+ . fmap Sum
56+
57+{-# INLINE foldIterateM #-}
58+foldIterateM :: Monad m => Stream m Int -> m ()
59+foldIterateM =
60+ Stream.fold FL.drain
61+ . fmap getSum
62+ . Stream.foldIterateM
63+ (return . FL.take 2 . FL.sconcat) (return (Sum 0))
64+ . fmap Sum
65+
66+{-# INLINE refoldIterateM #-}
67+refoldIterateM :: Monad m => Stream m Int -> m ()
68+refoldIterateM =
69+ Stream.fold FL.drain
70+ . fmap getSum
71+ . Stream.refoldIterateM
72+ (Refold.take 2 Refold.sconcat) (return (Sum 0))
73+ . fmap Sum
74+
75+{-# INLINE parseMany #-}
76+parseMany :: MonadCatch m => Int -> Stream m Int -> m ()
77+parseMany n =
78+ Stream.fold FL.drain
79+ . fmap getSum
80+ . Stream.parseMany (PR.fromFold $ FL.take n FL.mconcat)
81+ . fmap Sum
82+
83+{-# INLINE parseManyD #-}
84+parseManyD :: MonadCatch m => Int -> Stream m Int -> m ()
85+parseManyD n =
86+ Stream.fold FL.drain
87+ . fmap getSum
88+ . Stream.parseManyD (ParserD.fromFold $ FL.take n FL.mconcat)
89+ . fmap Sum
90+
91+{-# INLINE parseIterate #-}
92+parseIterate :: MonadCatch m => Int -> Stream m Int -> m ()
93+parseIterate n =
94+ Stream.fold FL.drain
95+ . fmap getSum
96+ . Stream.parseIterate (\_ -> PR.fromFold $ FL.take n FL.mconcat) 0
97+ . fmap Sum
98+
99+{-# INLINE arraysOf #-}
100+arraysOf :: (MonadCatch m, MonadIO m) => Int -> Stream m Int -> m ()
101+arraysOf n =
102+ Stream.fold FL.drain
103+ . Stream.arraysOf n
104+
105+o_1_space_grouping :: Int -> [Benchmark]
106+o_1_space_grouping value =
107+ -- Buffering operations using heap proportional to group/window sizes.
108+ [ bgroup "reduce"
109+ [ benchIOSink value "foldMany" foldMany
110+ , benchIOSink value "foldManyPost" foldManyPost
111+ , benchIOSink value "refoldMany" refoldMany
112+ , benchIOSink value "foldIterateM" foldIterateM
113+ , benchIOSink value "refoldIterateM" refoldIterateM
114+ , benchIOSink value "parseMany" $ parseMany value
115+ , benchIOSink value "parseManyD" $ parseManyD value
116+ , benchIOSink value "parseIterate" $ parseIterate value
117+ , benchIOSink value "arraysOf" $ arraysOf value
118+ ]
119+ ]
120+
121+benchmarks :: String -> Int -> [Benchmark]
122+benchmarks moduleName size =
123+ [ bgroup (o_1_space_prefix moduleName) $ o_1_space_grouping size
124+ ]
benchmark/Streamly/Benchmark/Prelude/Serial/Split.hs → benchmark/Streamly/Benchmark/Data/Stream/Split.hsrenamed+2−2
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Streamly.Benchmark.Prelude.Serial.Split
2+-- Module : Stream.Split
33-- Copyright : (c) 2019 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -18,7 +18,7 @@
1818{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
1919#endif
2020
21−module Serial.Split (benchmarks) where
21+module Stream.Split (benchmarks) where
2222
2323import Data.Char (ord)
2424import Data.Word (Word8)
benchmark/Streamly/Benchmark/Prelude/Serial/Transformation.hs → benchmark/Streamly/Benchmark/Data/Stream/Transformation.hsrenamed+166−98
@@ -1,5 +1,5 @@
11-- |
2−-- Module : Serial.Transformation
2+-- Module : Stream.Transformation
33-- Copyright : (c) 2018 Composewell Technologies
44-- License : BSD-3-Clause
55-- Maintainer : streamly@composewell.com
@@ -18,29 +18,35 @@
1818{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
1919#endif
2020
21−module Serial.Transformation (benchmarks) where
21+module Stream.Transformation (benchmarks) where
2222
23−import Control.DeepSeq (NFData(..))
2423import Control.Monad.IO.Class (MonadIO(..))
25−import Data.Functor.Identity (Identity)
24+
2625import System.Random (randomRIO)
2726
28−#ifdef INSPECTION
29−import Test.Inspection
30−#endif
27+import qualified Streamly.Internal.Data.Fold as FL
3128
29+#ifdef USE_PRELUDE
30+import Streamly.Prelude (fromSerial, MonadAsync)
31+import Streamly.Benchmark.Prelude
32+import Streamly.Internal.Data.Time.Units
33+import qualified Streamly.Benchmark.Prelude as BP
3234import qualified Streamly.Prelude as S
33−import qualified Streamly.Internal.Data.Stream as Stream
3435import qualified Streamly.Internal.Data.Stream.IsStream as Internal
35−import qualified Streamly.Internal.Data.Fold as FL
3636import qualified Streamly.Internal.Data.Unfold as Unfold
37+#else
38+import Control.DeepSeq (NFData(..))
39+import Data.Functor.Identity (Identity)
40+import Stream.Common
41+import qualified Streamly.Internal.Data.Stream as Stream
42+import qualified Streamly.Internal.Data.Stream as S
43+import qualified Streamly.Internal.Data.Stream as Internal
3744import qualified Prelude
45+#endif
3846
3947import Gauge
40−import Streamly.Prelude (SerialT, fromSerial, MonadAsync)
48+import Streamly.Internal.Data.Stream.Serial (SerialT)
4149import Streamly.Benchmark.Common
42−import Streamly.Benchmark.Prelude
43−import Streamly.Internal.Data.Time.Units
4450import Prelude hiding (sequence, mapM, fmap)
4551
4652-------------------------------------------------------------------------------
@@ -54,7 +60,7 @@ import Prelude hiding (sequence, mapM, fmap)
5460-------------------------------------------------------------------------------
5561-- Traversable Instance
5662-------------------------------------------------------------------------------
57−
63+#ifndef USE_PRELUDE
5864{-# INLINE traversableTraverse #-}
5965traversableTraverse :: SerialT Identity Int -> IO (SerialT Identity Int)
6066traversableTraverse = traverse return
@@ -89,42 +95,69 @@ o_n_space_traversable value =
8995 , benchPureSinkIO value "sequence" traversableSequence
9096 ]
9197 ]
98+#endif
9299
100+#ifdef USE_PRELUDE
101+{-# INLINE composeNG #-}
102+composeNG ::
103+ (S.IsStream t, Monad m)
104+ => Int
105+ -> (t m Int -> S.SerialT m Int)
106+ -> t m Int
107+ -> m ()
108+composeNG = BP.composeN
109+#else
110+{-# INLINE composeNG #-}
111+composeNG ::
112+ (Monad m)
113+ => Int
114+ -> (SerialT m Int -> SerialT m Int)
115+ -> SerialT m Int
116+ -> m ()
117+composeNG _n = return $ Stream.fold FL.drain
118+#endif
93119-------------------------------------------------------------------------------
94120-- maps and scans
95121-------------------------------------------------------------------------------
96122
123+
124+{-# INLINE scan #-}
125+scan :: MonadIO m => Int -> SerialT m Int -> m ()
126+scan n = composeNG n $ S.scan FL.sum
127+
128+{-# INLINE tap #-}
129+tap :: MonadIO m => Int -> SerialT m Int -> m ()
130+tap n = composeNG n $ S.tap FL.sum
131+
132+#ifdef USE_PRELUDE
97133{-# INLINE scanl' #-}
98134scanl' :: MonadIO m => Int -> SerialT m Int -> m ()
99−scanl' n = composeN n $ S.scanl' (+) 0
135+scanl' n = composeNG n $ S.scanl' (+) 0
100136
101137{-# INLINE scanlM' #-}
102138scanlM' :: MonadIO m => Int -> SerialT m Int -> m ()
103−scanlM' n = composeN n $ S.scanlM' (\b a -> return $ b + a) (return 0)
139+scanlM' n = composeNG n $ S.scanlM' (\b a -> return $ b + a) (return 0)
104140
105141{-# INLINE scanl1' #-}
106142scanl1' :: MonadIO m => Int -> SerialT m Int -> m ()
107−scanl1' n = composeN n $ S.scanl1' (+)
143+scanl1' n = composeNG n $ S.scanl1' (+)
108144
109145{-# INLINE scanl1M' #-}
110146scanl1M' :: MonadIO m => Int -> SerialT m Int -> m ()
111−scanl1M' n = composeN n $ S.scanl1M' (\b a -> return $ b + a)
112−
113−{-# INLINE scan #-}
114−scan :: MonadIO m => Int -> SerialT m Int -> m ()
115−scan n = composeN n $ S.scan FL.sum
147+scanl1M' n = composeNG n $ S.scanl1M' (\b a -> return $ b + a)
116148
117149{-# INLINE postscanl' #-}
118150postscanl' :: MonadIO m => Int -> SerialT m Int -> m ()
119−postscanl' n = composeN n $ S.postscanl' (+) 0
151+postscanl' n = composeNG n $ S.postscanl' (+) 0
120152
121153{-# INLINE postscanlM' #-}
122154postscanlM' :: MonadIO m => Int -> SerialT m Int -> m ()
123−postscanlM' n = composeN n $ S.postscanlM' (\b a -> return $ b + a) (return 0)
155+postscanlM' n = composeNG n $ S.postscanlM' (\b a -> return $ b + a) (return 0)
156+
124157
125158{-# INLINE postscan #-}
126159postscan :: MonadIO m => Int -> SerialT m Int -> m ()
127−postscan n = composeN n $ S.postscan FL.sum
160+postscan n = composeNG n $ S.postscan FL.sum
128161
129162{-# INLINE sequence #-}
130163sequence ::
@@ -134,10 +167,6 @@ sequence ::
134167 -> m ()
135168sequence t = S.drain . t . S.sequence
136169
137−{-# INLINE tap #-}
138−tap :: MonadIO m => Int -> SerialT m Int -> m ()
139−tap n = composeN n $ S.tap FL.sum
140−
141170{-# INLINE pollCounts #-}
142171pollCounts :: Int -> SerialT IO Int -> IO ()
143172pollCounts n =
@@ -151,26 +180,26 @@ pollCounts n =
151180timestamped :: (S.MonadAsync m) => SerialT m Int -> m ()
152181timestamped = S.drain . Internal.timestamped
153182
183+{-# INLINE trace #-}
184+trace :: MonadAsync m => Int -> SerialT m Int -> m ()
185+trace n = composeNG n $ Internal.trace return
186+#endif
187+
154188{-# INLINE foldrS #-}
155189foldrS :: MonadIO m => Int -> SerialT m Int -> m ()
156−foldrS n = composeN n $ Internal.foldrS S.cons S.nil
190+foldrS n = composeNG n $ Internal.foldrS S.cons S.nil
157191
158192{-# INLINE foldrSMap #-}
159193foldrSMap :: MonadIO m => Int -> SerialT m Int -> m ()
160−foldrSMap n = composeN n $ Internal.foldrS (\x xs -> x + 1 `S.cons` xs) S.nil
194+foldrSMap n = composeNG n $ Internal.foldrS (\x xs -> x + 1 `S.cons` xs) S.nil
161195
162196{-# INLINE foldrT #-}
163197foldrT :: MonadIO m => Int -> SerialT m Int -> m ()
164−foldrT n = composeN n $ Internal.foldrT S.cons S.nil
198+foldrT n = composeNG n $ Internal.foldrT S.cons S.nil
165199
166200{-# INLINE foldrTMap #-}
167201foldrTMap :: MonadIO m => Int -> SerialT m Int -> m ()
168−foldrTMap n = composeN n $ Internal.foldrT (\x xs -> x + 1 `S.cons` xs) S.nil
169−
170−
171−{-# INLINE trace #-}
172−trace :: MonadAsync m => Int -> SerialT m Int -> m ()
173−trace n = composeN n $ Internal.trace return
202+foldrTMap n = composeNG n $ Internal.foldrT (\x xs -> x + 1 `S.cons` xs) S.nil
174203
175204o_1_space_mapping :: Int -> [Benchmark]
176205o_1_space_mapping value =
@@ -182,13 +211,13 @@ o_1_space_mapping value =
182211 , benchIOSink value "foldrSMap" (foldrSMap 1)
183212 , benchIOSink value "foldrT" (foldrT 1)
184213 , benchIOSink value "foldrTMap" (foldrTMap 1)
185−
214+#ifdef USE_PRELUDE
186215 -- Mapping
187216 , benchIOSink value "map" (mapN fromSerial 1)
188217 , bench "sequence" $ nfIO $ randomRIO (1, 1000) >>= \n ->
189218 sequence fromSerial (sourceUnfoldrAction value n)
190219 , benchIOSink value "mapM" (mapM fromSerial 1)
191− , benchIOSink value "tap" (tap 1)
220+
192221 , benchIOSink value "pollCounts 1 second" (pollCounts 1)
193222 , benchIOSink value "timestamped" timestamped
194223
@@ -199,12 +228,15 @@ o_1_space_mapping value =
199228 , benchIOSink value "scanl1M'" (scanl1M' 1)
200229 , benchIOSink value "postscanl'" (postscanl' 1)
201230 , benchIOSink value "postscanlM'" (postscanlM' 1)
202−
203− , benchIOSink value "scan" (scan 1)
204231 , benchIOSink value "postscan" (postscan 1)
232+#endif
233+ , benchIOSink value "scan" (scan 1)
234+ , benchIOSink value "tap" (tap 1)
205235 ]
206236 ]
207237
238+
239+#ifdef USE_PRELUDE
208240o_1_space_mappingX4 :: Int -> [Benchmark]
209241o_1_space_mappingX4 value =
210242 [ bgroup "mappingX4"
@@ -218,10 +250,10 @@ o_1_space_mappingX4 value =
218250 , benchIOSink value "scanl1M'" (scanl1M' 4)
219251 , benchIOSink value "postscanl'" (postscanl' 4)
220252 , benchIOSink value "postscanlM'" (postscanlM' 4)
221−
222253 ]
223254 ]
224255
256+
225257{-# INLINE sieveScan #-}
226258sieveScan :: Monad m => SerialT m Int -> SerialT m Int
227259sieveScan =
@@ -252,85 +284,89 @@ o_1_space_functor value =
252284 , benchIOSink value "fmap x 4" (fmapN fromSerial 4)
253285 ]
254286 ]
255−
287+#else
288+{-# INLINE foldFilterEven #-}
289+foldFilterEven :: MonadIO m => SerialT m Int -> m ()
290+foldFilterEven = Stream.fold FL.drain . Stream.foldFilter (FL.satisfy even)
291+#endif
256292-------------------------------------------------------------------------------
257293-- Size reducing transformations (filtering)
258294-------------------------------------------------------------------------------
259295
260296{-# INLINE filterEven #-}
261297filterEven :: MonadIO m => Int -> SerialT m Int -> m ()
262−filterEven n = composeN n $ S.filter even
298+filterEven n = composeNG n $ S.filter even
263299
264300{-# INLINE filterAllOut #-}
265301filterAllOut :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
266−filterAllOut value n = composeN n $ S.filter (> (value + 1))
302+filterAllOut value n = composeNG n $ S.filter (> (value + 1))
267303
268304{-# INLINE filterAllIn #-}
269305filterAllIn :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
270−filterAllIn value n = composeN n $ S.filter (<= (value + 1))
306+filterAllIn value n = composeNG n $ S.filter (<= (value + 1))
271307
272308{-# INLINE filterMEven #-}
273309filterMEven :: MonadIO m => Int -> SerialT m Int -> m ()
274−filterMEven n = composeN n $ S.filterM (return . even)
310+filterMEven n = composeNG n $ S.filterM (return . even)
275311
276312{-# INLINE filterMAllOut #-}
277313filterMAllOut :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
278−filterMAllOut value n = composeN n $ S.filterM (\x -> return $ x > (value + 1))
314+filterMAllOut value n = composeNG n $ S.filterM (\x -> return $ x > (value + 1))
279315
280316{-# INLINE filterMAllIn #-}
281317filterMAllIn :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
282−filterMAllIn value n = composeN n $ S.filterM (\x -> return $ x <= (value + 1))
283−
284−{-# INLINE foldFilterEven #-}
285−foldFilterEven :: MonadIO m => Int -> SerialT m Int -> m ()
286−foldFilterEven n = composeN n $ Stream.foldFilter (FL.satisfy even)
318+filterMAllIn value n = composeNG n $ S.filterM (\x -> return $ x <= (value + 1))
287319
288320{-# INLINE _takeOne #-}
289321_takeOne :: MonadIO m => Int -> SerialT m Int -> m ()
290−_takeOne n = composeN n $ S.take 1
322+_takeOne n = composeNG n $ S.take 1
291323
292324{-# INLINE takeAll #-}
293325takeAll :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
294−takeAll value n = composeN n $ S.take (value + 1)
326+takeAll value n = composeNG n $ S.take (value + 1)
295327
296328{-# INLINE takeWhileTrue #-}
297329takeWhileTrue :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
298−takeWhileTrue value n = composeN n $ S.takeWhile (<= (value + 1))
330+takeWhileTrue value n = composeNG n $ S.takeWhile (<= (value + 1))
299331
300332{-# INLINE takeWhileMTrue #-}
301333takeWhileMTrue :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
302−takeWhileMTrue value n = composeN n $ S.takeWhileM (return . (<= (value + 1)))
334+takeWhileMTrue value n = composeNG n $ S.takeWhileM (return . (<= (value + 1)))
303335
336+#ifdef USE_PRELUDE
304337{-# INLINE takeInterval #-}
305338takeInterval :: NanoSecond64 -> Int -> SerialT IO Int -> IO ()
306339takeInterval i n = composeN n (Internal.takeInterval i)
307340
341+
308342#ifdef INSPECTION
309343-- inspect $ hasNoType 'takeInterval ''SPEC
310344inspect $ hasNoTypeClasses 'takeInterval
311345-- inspect $ 'takeInterval `hasNoType` ''D.Step
312346#endif
347+#endif
313348
314349{-# INLINE dropOne #-}
315350dropOne :: MonadIO m => Int -> SerialT m Int -> m ()
316−dropOne n = composeN n $ S.drop 1
351+dropOne n = composeNG n $ S.drop 1
317352
318353{-# INLINE dropAll #-}
319354dropAll :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
320−dropAll value n = composeN n $ S.drop (value + 1)
355+dropAll value n = composeNG n $ S.drop (value + 1)
321356
322357{-# INLINE dropWhileTrue #-}
323358dropWhileTrue :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
324−dropWhileTrue value n = composeN n $ S.dropWhile (<= (value + 1))
359+dropWhileTrue value n = composeNG n $ S.dropWhile (<= (value + 1))
325360
326361{-# INLINE dropWhileMTrue #-}
327362dropWhileMTrue :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
328−dropWhileMTrue value n = composeN n $ S.dropWhileM (return . (<= (value + 1)))
363+dropWhileMTrue value n = composeNG n $ S.dropWhileM (return . (<= (value + 1)))
329364
330365{-# INLINE dropWhileFalse #-}
331366dropWhileFalse :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
332−dropWhileFalse value n = composeN n $ S.dropWhile (> (value + 1))
367+dropWhileFalse value n = composeNG n $ S.dropWhile (> (value + 1))
333368
369+#ifdef USE_PRELUDE
334370-- XXX Decide on the time interval
335371{-# INLINE _intervalsOfSum #-}
336372_intervalsOfSum :: MonadAsync m => Double -> Int -> SerialT m Int -> m ()
@@ -344,28 +380,30 @@ dropInterval i n = composeN n (Internal.dropInterval i)
344380inspect $ hasNoTypeClasses 'dropInterval
345381-- inspect $ 'dropInterval `hasNoType` ''D.Step
346382#endif
383+#endif
347384
348385{-# INLINE findIndices #-}
349386findIndices :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
350−findIndices value n = composeN n $ S.findIndices (== (value + 1))
387+findIndices value n = composeNG n $ S.findIndices (== (value + 1))
351388
352389{-# INLINE elemIndices #-}
353390elemIndices :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
354−elemIndices value n = composeN n $ S.elemIndices (value + 1)
391+elemIndices value n = composeNG n $ S.elemIndices (value + 1)
355392
356393{-# INLINE deleteBy #-}
357394deleteBy :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
358−deleteBy value n = composeN n $ S.deleteBy (>=) (value + 1)
395+deleteBy value n = composeNG n $ S.deleteBy (>=) (value + 1)
359396
360397-- uniq . uniq == uniq, composeN 2 ~ composeN 1
361398{-# INLINE uniq #-}
362399uniq :: MonadIO m => Int -> SerialT m Int -> m ()
363−uniq n = composeN n S.uniq
400+uniq n = composeNG n S.uniq
364401
402+#ifdef USE_PRELUDE
365403{-# INLINE mapMaybe #-}
366404mapMaybe :: MonadIO m => Int -> SerialT m Int -> m ()
367405mapMaybe n =
368− composeN n $
406+ composeNG n $
369407 S.mapMaybe
370408 (\x ->
371409 if odd x
@@ -375,12 +413,13 @@ mapMaybe n =
375413{-# INLINE mapMaybeM #-}
376414mapMaybeM :: S.MonadAsync m => Int -> SerialT m Int -> m ()
377415mapMaybeM n =
378− composeN n $
416+ composeNG n $
379417 S.mapMaybeM
380418 (\x ->
381419 if odd x
382420 then return Nothing
383421 else return $ Just x)
422+#endif
384423
385424o_1_space_filtering :: Int -> [Benchmark]
386425o_1_space_filtering value =
@@ -392,23 +431,26 @@ o_1_space_filtering value =
392431 , benchIOSink value "filterM-even" (filterMEven 1)
393432 , benchIOSink value "filterM-all-out" (filterMAllOut value 1)
394433 , benchIOSink value "filterM-all-in" (filterMAllIn value 1)
395−
396− , benchIOSink value "foldFilter-even" (foldFilterEven 1)
434+#ifndef USE_PRELUDE
435+ , benchIOSink value "foldFilter-even" foldFilterEven
436+#endif
397437
398438 -- Trimming
399439 , benchIOSink value "take-all" (takeAll value 1)
400− , benchIOSink
401− value
402− "takeInterval-all"
403− (takeInterval (NanoSecond64 maxBound) 1)
404440 , benchIOSink value "takeWhile-true" (takeWhileTrue value 1)
405441 -- , benchIOSink value "takeWhileM-true" (_takeWhileMTrue value 1)
406442 , benchIOSink value "drop-one" (dropOne 1)
407443 , benchIOSink value "drop-all" (dropAll value 1)
444+#ifdef USE_PRELUDE
445+ , benchIOSink
446+ value
447+ "takeInterval-all"
448+ (takeInterval (NanoSecond64 maxBound) 1)
408449 , benchIOSink
409450 value
410451 "dropInterval-all"
411452 (dropInterval (NanoSecond64 maxBound) 1)
453+#endif
412454 , benchIOSink value "dropWhile-true" (dropWhileTrue value 1)
413455 -- , benchIOSink value "dropWhileM-true" (_dropWhileMTrue value 1)
414456 , benchIOSink
@@ -418,17 +460,18 @@ o_1_space_filtering value =
418460 , benchIOSink value "deleteBy" (deleteBy value 1)
419461
420462 , benchIOSink value "uniq" (uniq 1)
421−
463+#ifdef USE_PRELUDE
422464 -- Map and filter
423465 , benchIOSink value "mapMaybe" (mapMaybe 1)
424466 , benchIOSink value "mapMaybeM" (mapMaybeM 1)
425−
467+#endif
426468 -- Searching (stateful map and filter)
427469 , benchIOSink value "findIndices" (findIndices value 1)
428470 , benchIOSink value "elemIndices" (elemIndices value 1)
429471 ]
430472 ]
431473
474+
432475o_1_space_filteringX4 :: Int -> [Benchmark]
433476o_1_space_filteringX4 value =
434477 [ bgroup "filteringX4"
@@ -440,7 +483,7 @@ o_1_space_filteringX4 value =
440483 , benchIOSink value "filterM-all-out" (filterMAllOut value 4)
441484 , benchIOSink value "filterM-all-in" (filterMAllIn value 4)
442485
443− , benchIOSink value "foldFilter-even" (foldFilterEven 4)
486+ --, benchIOSink value "foldFilter-even" (foldFilterEven 4)
444487
445488 -- trimming
446489 , benchIOSink value "take-all" (takeAll value 4)
@@ -458,10 +501,11 @@ o_1_space_filteringX4 value =
458501
459502 , benchIOSink value "uniq" (uniq 4)
460503
504+#ifdef USE_PRELUDE
461505 -- map and filter
462506 , benchIOSink value "mapMaybe" (mapMaybe 4)
463507 , benchIOSink value "mapMaybeM" (mapMaybeM 4)
464−
508+#endif
465509 -- searching
466510 , benchIOSink value "findIndices" (findIndices value 4)
467511 , benchIOSink value "elemIndices" (elemIndices value 4)
@@ -471,28 +515,29 @@ o_1_space_filteringX4 value =
471515-------------------------------------------------------------------------------
472516-- Size increasing transformations (insertions)
473517-------------------------------------------------------------------------------
474−
518+#ifdef USE_PRELUDE
475519{-# INLINE intersperse #-}
476520intersperse :: S.MonadAsync m => Int -> Int -> SerialT m Int -> m ()
477−intersperse value n = composeN n $ S.intersperse (value + 1)
521+intersperse value n = composeNG n $ S.intersperse (value + 1)
478522
479523{-# INLINE intersperseM #-}
480524intersperseM :: S.MonadAsync m => Int -> Int -> SerialT m Int -> m ()
481−intersperseM value n = composeN n $ S.intersperseM (return $ value + 1)
482−
483−{-# INLINE insertBy #-}
484−insertBy :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
485−insertBy value n = composeN n $ S.insertBy compare (value + 1)
525+intersperseM value n = composeNG n $ S.intersperseM (return $ value + 1)
486526
487527{-# INLINE interposeSuffix #-}
488528interposeSuffix :: S.MonadAsync m => Int -> Int -> SerialT m Int -> m ()
489529interposeSuffix value n =
490− composeN n $ Internal.interposeSuffix (value + 1) Unfold.identity
530+ composeNG n $ Internal.interposeSuffix (value + 1) Unfold.identity
491531
492532{-# INLINE intercalateSuffix #-}
493533intercalateSuffix :: S.MonadAsync m => Int -> Int -> SerialT m Int -> m ()
494534intercalateSuffix value n =
495− composeN n $ Internal.intercalateSuffix Unfold.identity (value + 1)
535+ composeNG n $ Internal.intercalateSuffix Unfold.identity (value + 1)
536+
537+{-# INLINE insertBy #-}
538+insertBy :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
539+insertBy value n = composeNG n $ S.insertBy compare (value + 1)
540+
496541
497542o_1_space_inserting :: Int -> [Benchmark]
498543o_1_space_inserting value =
@@ -509,14 +554,14 @@ o_1_space_insertingX4 :: Int -> [Benchmark]
509554o_1_space_insertingX4 value =
510555 [ bgroup "insertingX4"
511556 [ benchIOSink value "intersperse" (intersperse value 4)
512− , benchIOSink value "insertBy" (insertBy value 4)
557+ -- , benchIOSink value "insertBy" (insertBy value 4)
513558 ]
514559 ]
515−
560+#endif
516561-------------------------------------------------------------------------------
517562-- Indexing
518563-------------------------------------------------------------------------------
519−
564+#ifdef USE_PRELUDE
520565{-# INLINE indexed #-}
521566indexed :: MonadIO m => Int -> SerialT m Int -> m ()
522567indexed n = composeN n (S.map snd . S.indexed)
@@ -541,6 +586,24 @@ o_1_space_indexingX4 value =
541586 ]
542587 ]
543588
589+#else
590+{-# INLINE indexed #-}
591+indexed :: MonadIO m => SerialT m Int -> m ()
592+indexed = Stream.fold FL.drain . Prelude.fmap snd . Stream.indexed
593+
594+{-# INLINE indexedR #-}
595+indexedR :: MonadIO m => Int -> SerialT m Int -> m ()
596+indexedR value = Stream.fold FL.drain . (Prelude.fmap snd . Stream.indexedR value)
597+
598+o_1_space_indexing :: Int -> [Benchmark]
599+o_1_space_indexing value =
600+ [ bgroup "indexing"
601+ [ benchIOSink value "indexed" indexed
602+ , benchIOSink value "indexedR" (indexedR value)
603+ ]
604+ ]
605+#endif
606+
544607-------------------------------------------------------------------------------
545608-- Main
546609-------------------------------------------------------------------------------
@@ -551,18 +614,23 @@ o_1_space_indexingX4 value =
551614benchmarks :: String -> Int -> [Benchmark]
552615benchmarks moduleName size =
553616 [ bgroup (o_1_space_prefix moduleName) $ Prelude.concat
554− [ o_1_space_functor size
555− , o_1_space_mapping size
556− , o_1_space_mappingX4 size
617+ [ o_1_space_mapping size
618+ , o_1_space_indexing size
557619 , o_1_space_filtering size
558620 , o_1_space_filteringX4 size
621+#ifdef USE_PRELUDE
622+ , o_1_space_functor size
623+ , o_1_space_mappingX4 size
559624 , o_1_space_inserting size
560625 , o_1_space_insertingX4 size
561− , o_1_space_indexing size
562626 , o_1_space_indexingX4 size
627+#endif
563628 ]
564− , bgroup (o_n_space_prefix moduleName) $ Prelude.concat
565− [ o_n_space_traversable size
566− , o_n_space_mapping size
567− ]
629+
630+ , bgroup (o_n_space_prefix moduleName) $
631+#ifdef USE_PRELUDE
632+ o_n_space_mapping size
633+#else
634+ o_n_space_traversable size
635+#endif
568636 ]
benchmark/bench-runner/Main.hs+9−9
@@ -35,22 +35,22 @@ rtsOpts exeName benchName0 = unwords [general, exeSpecific, benchSpecific]
3535 `isPrefixOf` benchName = "-K2M -M256M"
3636 | "Prelude.Rate/o-1-space." `isPrefixOf` benchName = "-K128K"
3737 | "Prelude.Rate/o-1-space.asyncly." `isPrefixOf` benchName = "-K128K"
38− | "Prelude.Serial/o-1-space.mixed.sum-product-fold" == benchName =
38+ | "Data.Stream/o-1-space.mixed.sum-product-fold" == benchName =
3939 "-K64M"
40− | "Prelude.Serial/o-n-heap.grouping.classifySessionsOf"
40+ | "Data.Stream/o-n-heap.grouping.classifySessionsOf"
4141 `isPrefixOf` benchName = "-K1M -M32M"
42− | "Prelude.Serial/o-n-heap.Functor." `isPrefixOf` benchName =
42+ | "Data.Stream/o-n-heap.Functor." `isPrefixOf` benchName =
4343 "-K4M -M32M"
44− | "Prelude.Serial/o-n-heap.transformer." `isPrefixOf` benchName =
44+ | "Data.Stream/o-n-heap.transformer." `isPrefixOf` benchName =
4545 "-K8M -M64M"
46− | "Prelude.Serial/o-n-space.Functor." `isPrefixOf` benchName =
46+ | "Data.Stream/o-n-space.Functor." `isPrefixOf` benchName =
4747 "-K4M -M64M"
48− | "Prelude.Serial/o-n-space.Applicative." `isPrefixOf` benchName =
48+ | "Data.Stream/o-n-space.Applicative." `isPrefixOf` benchName =
4949 "-K8M -M128M"
50− | "Prelude.Serial/o-n-space.Monad." `isPrefixOf` benchName =
50+ | "Data.Stream/o-n-space.Monad." `isPrefixOf` benchName =
5151 "-K8M -M64M"
52− | "Prelude.Serial/o-n-space.grouping." `isPrefixOf` benchName = ""
53− | "Prelude.Serial/o-n-space." `isPrefixOf` benchName = "-K4M"
52+ | "Data.Stream/o-n-space.grouping." `isPrefixOf` benchName = ""
53+ | "Data.Stream/o-n-space." `isPrefixOf` benchName = "-K4M"
5454 | "Prelude.WSerial/o-n-space." `isPrefixOf` benchName = "-K4M"
5555 | "Prelude.Async/o-n-space.monad-outer-product." `isPrefixOf` benchName =
5656 "-K4M"
benchmark/streamly-benchmarks.cabal+38−25
@@ -64,6 +64,10 @@ flag bench-core
6464 manual: True
6565 default: False
6666
67+flag use-prelude
68+ description: Use Streamly.Prelude instead of Streamly.Data.Stream for serial benchmarks
69+ manual: True
70+ default: False
6771-------------------------------------------------------------------------------
6872-- Common stanzas
6973-------------------------------------------------------------------------------
@@ -71,6 +75,9 @@ flag bench-core
7175common compile-options
7276 default-language: Haskell2010
7377
78+ if flag(use-prelude)
79+ cpp-options: -DUSE_PRELUDE
80+
7481 if flag(dev)
7582 cpp-options: -DDEVBUILD
7683
@@ -201,31 +208,6 @@ common bench-options-threaded
201208-- Serial Streams
202209-------------------------------------------------------------------------------
203210
204−benchmark Prelude.Serial
205− import: bench-options
206− type: exitcode-stdio-1.0
207− hs-source-dirs: Streamly/Benchmark/Prelude
208− main-is: Serial.hs
209− other-modules:
210− Serial.Generation
211− , Serial.Elimination
212− , Serial.Transformation
213− , Serial.NestedStream
214− , Serial.NestedFold
215− , Serial.Split
216− , Serial.Exceptions
217− , Serial.Lift
218− if flag(bench-core) || impl(ghcjs)
219− buildable: False
220− else
221− buildable: True
222− if flag(limit-build-mem)
223− if flag(dev)
224− ghc-options: +RTS -M3500M -RTS
225− else
226− ghc-options: +RTS -M2500M -RTS
227−
228−
229211benchmark Prelude.WSerial
230212 import: bench-options
231213 type: exitcode-stdio-1.0
@@ -405,6 +387,37 @@ benchmark Data.Parser
405387-------------------------------------------------------------------------------
406388-- Raw Streams
407389-------------------------------------------------------------------------------
390+benchmark Data.Stream
391+ import: bench-options
392+ type: exitcode-stdio-1.0
393+ hs-source-dirs: Streamly/Benchmark/Data
394+ main-is: Stream.hs
395+ other-modules:
396+ Stream.Eliminate
397+ Stream.Exceptions
398+ Stream.Generate
399+ Stream.Lift
400+ Stream.Transformation
401+ if flag(use-prelude)
402+ other-modules:
403+ Stream.NestedFold
404+ Stream.NestedStream
405+ Stream.Split
406+ else
407+ other-modules:
408+ Stream.Common
409+ Stream.Reduce
410+
411+ if flag(bench-core) || impl(ghcjs)
412+ buildable: False
413+ else
414+ buildable: True
415+ build-depends: exceptions >= 0.8 && < 0.11
416+ if flag(limit-build-mem)
417+ if flag(dev)
418+ ghc-options: +RTS -M3500M -RTS
419+ else
420+ ghc-options: +RTS -M2000M -RTS
408421
409422benchmark Data.Stream.StreamD
410423 import: bench-options
hie.yaml+2−18
@@ -30,6 +30,8 @@ cradle:
3030 component: "bench:Data.Stream.StreamD"
3131 - path: "./benchmark/Streamly/Benchmark/Data/Stream/StreamK.hs"
3232 component: "bench:Data.Stream.StreamK"
33+ - path: "./benchmark/Streamly/Benchmark/Data/Stream/*.hs"
34+ component: "bench:Data.Stream"
3335 - path: "./benchmark/Streamly/Benchmark/Data/Unfold.hs"
3436 component: "bench:Data.Unfold"
3537 - path: "./benchmark/Streamly/Benchmark/FileSystem/Handle/Read.hs"
@@ -44,24 +46,6 @@ cradle:
4446 component: "bench:Prelude.Merge"
4547 - path: "./benchmark/Streamly/Benchmark/Prelude/Parallel.hs"
4648 component: "bench:Prelude.Parallel"
47− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial.hs"
48− component: "bench:Prelude.Serial"
49− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Elimination.hs"
50− component: "bench:Prelude.Serial"
51− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Exceptions.hs"
52− component: "bench:Prelude.Serial"
53− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Generation.hs"
54− component: "bench:Prelude.Serial"
55− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial/NestedStream.hs"
56− component: "bench:Prelude.Serial"
57− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Split.hs"
58− component: "bench:Prelude.Serial"
59− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Transformation.hs"
60− component: "bench:Prelude.Serial"
61− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial/NestedFold.hs"
62− component: "bench:Prelude.Serial"
63− - path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Lift.hs"
64− component: "bench:Prelude.Serial"
6549 - path: "./benchmark/Streamly/Benchmark/Prelude/WSerial.hs"
6650 component: "bench:Prelude.WSerial"
6751 - path: "./benchmark/Streamly/Benchmark/Prelude/ZipSerial.hs"
streamly.cabal−1
@@ -65,7 +65,6 @@ extra-source-files:
6565 benchmark/Streamly/Benchmark/FileSystem/*.hs
6666 benchmark/Streamly/Benchmark/FileSystem/Handle/*.hs
6767 benchmark/Streamly/Benchmark/Prelude/*.hs
68− benchmark/Streamly/Benchmark/Prelude/Serial/*.hs
6968 benchmark/Streamly/Benchmark/Unicode/*.hs
7069 benchmark/lib/Streamly/Benchmark/*.hs
7170 benchmark/lib/Streamly/Benchmark/Common/*.hs
targets/Targets.hs+2−2
@@ -25,9 +25,9 @@ targets =
2525 )
2626
2727 -- Streams
28− , ("Prelude.Serial", ["serial_wserial_cmp"])
28+ , ("Data.Stream", ["serial_wserial_cmp"])
2929 , ("Prelude.WSerial", ["serial_wserial_cmp"])
30− , ("Prelude.Serial",
30+ , ("Data.Stream",
3131 [ "prelude_serial_grp"
3232 , "infinite_grp"
3333 , "serial_wserial_cmp"