From 10c48939bcc2a80fa0912600dbeaa6929188f3ef Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Wed, 8 Jul 2026 13:15:36 +0530 Subject: [PATCH 1/6] Use NOINLINE on stream benchmarking IO actions --- .../Benchmark/Data/Stream/Eliminate.hs | 33 +++++++ .../Benchmark/Data/Stream/Generate.hs | 19 ++++ .../Streamly/Benchmark/Data/Stream/Lift.hs | 4 + .../Benchmark/Data/Stream/Nesting/Basic.hs | 7 ++ .../Data/Stream/Nesting/LogicConcat.hs | 5 + .../Data/Stream/Nesting/LogicUnfold.hs | 7 ++ .../Benchmark/Data/Stream/Parse/Group.hs | 6 ++ .../Data/Stream/Prelude/Exceptions.hs | 99 ++++++++++++------- .../Benchmark/Data/Stream/Transform/Basic.hs | 67 +++++++++++++ .../Data/Stream/Transform/Composed.hs | 46 +++++++++ .../Benchmark/Data/Stream/Type/Basic.hs | 41 ++++++++ .../Benchmark/Data/Stream/Type/Logic.hs | 5 + .../Benchmark/Data/Stream/Type/MultiStream.hs | 20 ++++ .../Benchmark/Data/Stream/Type/Nested.hs | 23 ++++- 14 files changed, 344 insertions(+), 38 deletions(-) diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Eliminate.hs b/benchmark/Streamly/Benchmark/Data/Stream/Eliminate.hs index bd617e79d3..767d408773 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Eliminate.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Eliminate.hs @@ -50,6 +50,7 @@ import qualified Prelude -- Reductions ------------------------------------------------------------------------------- +{-# NOINLINE streamInit #-} streamInit :: Int -> IO () streamInit value = withStream value (S.init >=> Prelude.mapM_ S.drain) @@ -60,6 +61,7 @@ inspect $ 'streamInit `hasNoType` ''Fold.Step inspect $ 'streamInit `hasNoType` ''SPEC #endif +{-# NOINLINE mapM_ #-} mapM_ :: Int -> IO () mapM_ value = withStream value (S.mapM_ (\_ -> return ())) @@ -70,6 +72,7 @@ inspect $ 'mapM_ `hasNoType` ''Fold.Step inspect $ 'mapM_ `hasNoType` ''SPEC #endif +{-# NOINLINE streamLast #-} streamLast :: Int -> IO (Maybe Int) streamLast value = withStream value S.last @@ -80,6 +83,7 @@ inspect $ 'streamLast `hasNoType` ''Fold.Step inspect $ 'streamLast `hasNoType` ''SPEC #endif +{-# NOINLINE foldl1'Reduce #-} foldl1'Reduce :: Int -> IO (Maybe Int) foldl1'Reduce value = withStream value (S.fold (Fold.foldl1' (+))) @@ -88,6 +92,7 @@ inspect $ hasNoTypeClasses 'foldl1'Reduce inspect $ 'foldl1'Reduce `hasNoType` ''S.Step #endif +{-# NOINLINE foldl1'ReduceIdentity #-} foldl1'ReduceIdentity :: Int -> IO (Maybe Int) foldl1'ReduceIdentity value = withPureStream value (runIdentity . S.fold (Fold.foldl1' (+))) @@ -97,6 +102,7 @@ inspect $ hasNoTypeClasses 'foldl1'ReduceIdentity inspect $ 'foldl1'ReduceIdentity `hasNoType` ''S.Step #endif +{-# NOINLINE elem #-} elem :: Int -> IO Bool elem value = withStream value (S.elem (value + 1)) @@ -107,6 +113,7 @@ inspect $ 'elem `hasNoType` ''Fold.Step inspect $ 'elem `hasNoType` ''SPEC #endif +{-# NOINLINE notElem #-} notElem :: Int -> IO Bool notElem value = withStream value (S.notElem (value + 1)) @@ -117,6 +124,7 @@ inspect $ 'notElem `hasNoType` ''Fold.Step inspect $ 'notElem `hasNoType` ''SPEC #endif +{-# NOINLINE length #-} length :: Int -> IO Int length value = withStream value (S.fold Fold.length) @@ -127,6 +135,7 @@ inspect $ 'length `hasNoType` ''Fold.Step inspect $ 'length `hasNoType` ''SPEC #endif +{-# NOINLINE all #-} all :: Int -> IO Bool all value = withStream value (S.all (<= (value + 1))) @@ -137,6 +146,7 @@ inspect $ 'all `hasNoType` ''Fold.Step inspect $ 'all `hasNoType` ''SPEC #endif +{-# NOINLINE any #-} any :: Int -> IO Bool any value = withStream value (S.any (> (value + 1))) @@ -147,6 +157,7 @@ inspect $ 'any `hasNoType` ''Fold.Step inspect $ 'any `hasNoType` ''SPEC #endif +{-# NOINLINE and #-} and :: Int -> IO Bool and value = withStream value (S.fold Fold.and . S.map (<= (value + 1))) @@ -157,6 +168,7 @@ inspect $ 'and `hasNoType` ''Fold.Step inspect $ 'and `hasNoType` ''SPEC #endif +{-# NOINLINE or #-} or :: Int -> IO Bool or value = withStream value (S.fold Fold.or . S.map (> (value + 1))) @@ -167,6 +179,7 @@ inspect $ 'or `hasNoType` ''Fold.Step inspect $ 'or `hasNoType` ''SPEC #endif +{-# NOINLINE find #-} find :: Int -> IO (Maybe Int) find value = withStream value (S.find (== (value + 1))) @@ -177,6 +190,7 @@ inspect $ 'find `hasNoType` ''Fold.Step inspect $ 'find `hasNoType` ''SPEC #endif +{-# NOINLINE findM #-} findM :: Int -> IO (Maybe Int) findM value = withStream value (S.findM (\z -> return $ z == (value + 1))) @@ -187,6 +201,7 @@ inspect $ 'findM `hasNoType` ''Fold.Step inspect $ 'findM `hasNoType` ''SPEC #endif +{-# NOINLINE maximum #-} maximum :: Int -> IO (Maybe Int) maximum value = withStream value S.maximum @@ -197,6 +212,7 @@ inspect $ 'maximum `hasNoType` ''Fold.Step inspect $ 'maximum `hasNoType` ''SPEC #endif +{-# NOINLINE minimum #-} minimum :: Int -> IO (Maybe Int) minimum value = withStream value S.minimum @@ -207,6 +223,7 @@ inspect $ 'minimum `hasNoType` ''Fold.Step inspect $ 'minimum `hasNoType` ''SPEC #endif +{-# NOINLINE sum #-} sum :: Int -> IO Int sum value = withStream value (S.fold Fold.sum) @@ -217,6 +234,7 @@ inspect $ 'sum `hasNoType` ''Fold.Step inspect $ 'sum `hasNoType` ''SPEC #endif +{-# NOINLINE product #-} product :: Int -> IO Int product value = withStream value (S.fold Fold.product) @@ -227,6 +245,7 @@ inspect $ 'product `hasNoType` ''Fold.Step inspect $ 'product `hasNoType` ''SPEC #endif +{-# NOINLINE minimumBy #-} minimumBy :: Int -> IO (Maybe Int) minimumBy value = withStream value (S.minimumBy compare) @@ -237,6 +256,7 @@ inspect $ 'minimumBy `hasNoType` ''Fold.Step inspect $ 'minimumBy `hasNoType` ''SPEC #endif +{-# NOINLINE maximumBy #-} maximumBy :: Int -> IO (Maybe Int) maximumBy value = withStream value (S.maximumBy compare) @@ -247,6 +267,7 @@ inspect $ 'maximumBy `hasNoType` ''Fold.Step inspect $ 'maximumBy `hasNoType` ''SPEC #endif +{-# NOINLINE the #-} the :: Int -> IO (Maybe Int) the value = randomRIO (1, 1) >>= S.the . repeat value @@ -257,6 +278,7 @@ inspect $ 'the `hasNoType` ''Fold.Step inspect $ 'the `hasNoType` ''SPEC #endif +{-# NOINLINE indexOp #-} indexOp :: Int -> IO (Maybe Int) indexOp value = withStream value (S.!! value) @@ -267,6 +289,7 @@ inspect $ 'indexOp `hasNoType` ''Fold.Step inspect $ 'indexOp `hasNoType` ''SPEC #endif +{-# NOINLINE lookupNever #-} lookupNever :: Int -> IO (Maybe Int) lookupNever value = withStream value (S.lookup (value + 1) . S.map (\x -> (x, x))) @@ -278,14 +301,17 @@ inspect $ 'lookupNever `hasNoType` ''Fold.Step inspect $ 'lookupNever `hasNoType` ''SPEC #endif +{-# NOINLINE toListRev #-} toListRev :: Int -> IO [Int] toListRev value = withStream value S.toListRev -- NOTE: this is a Fold benchmark, used here only for comparison with toListRev +{-# NOINLINE toStreamRev #-} toStreamRev :: Int -> IO (Stream Identity Int) toStreamRev value = withStream value (S.fold Fold.toStreamRev) -- NOTE: this is a Fold benchmark, used here only for comparison with ToList +{-# NOINLINE toStream #-} toStream :: Int -> IO (Stream Identity Int) toStream value = withStream value (S.fold Fold.toStream) @@ -293,6 +319,7 @@ toStream value = withStream value (S.fold Fold.toStream) -- Multi-stream folds ------------------------------------------------------------------------------- +{-# NOINLINE isPrefixOf #-} isPrefixOf :: Int -> IO Bool isPrefixOf value = withStream value (\src -> S.isPrefixOf src src) @@ -303,6 +330,7 @@ inspect $ 'isPrefixOf `hasNoType` ''Fold.Step inspect $ 'isPrefixOf `hasNoType` ''SPEC #endif +{-# NOINLINE isSubsequenceOf #-} isSubsequenceOf :: Int -> IO Bool isSubsequenceOf value = withStream value (\src -> S.isSubsequenceOf src src) @@ -313,6 +341,7 @@ inspect $ 'isSubsequenceOf `hasNoType` ''Fold.Step inspect $ 'isSubsequenceOf `hasNoType` ''SPEC #endif +{-# NOINLINE stripPrefix #-} stripPrefix :: Int -> IO () stripPrefix value = withStream value (\src -> do _ <- S.stripPrefix src src @@ -329,10 +358,12 @@ inspect $ 'stripPrefix `hasNoType` ''SPEC -- Iterating using tail ------------------------------------------------------------------------------- +{-# NOINLINE tail #-} tail :: Int -> IO () tail value = withStream value go where go s = S.tail s >>= Prelude.mapM_ go +{-# NOINLINE nullHeadTail #-} nullHeadTail :: Int -> IO () nullHeadTail value = withStream value go where @@ -342,6 +373,7 @@ nullHeadTail value = withStream value go _ <- S.head s S.tail s >>= Prelude.mapM_ go +{-# NOINLINE nullTail #-} nullTail :: Int -> IO () nullTail value = withStream value go where @@ -349,6 +381,7 @@ nullTail value = withStream value go r <- S.null s when (not r) $ S.tail s >>= Prelude.mapM_ go +{-# NOINLINE headTail #-} headTail :: Int -> IO () headTail value = withStream value go where diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Generate.hs b/benchmark/Streamly/Benchmark/Data/Stream/Generate.hs index 03e75916a9..452f52d214 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Generate.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Generate.hs @@ -44,6 +44,7 @@ import Prelude hiding (repeat, replicate, iterate) fromListM :: Monad m => [m a] -> Stream m a fromListM = Stream.sequence . Stream.fromList +{-# NOINLINE sourceFromListM #-} sourceFromListM :: Int -> IO () sourceFromListM value = withDrain $ \n -> fromListM (fmap return [n..n+value]) @@ -54,6 +55,7 @@ inspect $ 'sourceFromListM `hasNoType` ''Fold.Step inspect $ 'sourceFromListM `hasNoType` ''SPEC #endif +{-# NOINLINE replicate #-} replicate :: Int -> IO () replicate value = withDrain (Stream.replicate value) @@ -68,6 +70,7 @@ inspect $ 'replicate `hasNoType` ''SPEC -- enumerate ------------------------------------------------------------------------------- +{-# NOINLINE sourceIntFromTo #-} sourceIntFromTo :: Int -> IO () sourceIntFromTo value = withDrain $ \n -> Stream.enumerateFromTo n (n + value) @@ -78,6 +81,7 @@ inspect $ 'sourceIntFromTo `hasNoType` ''Fold.Step inspect $ 'sourceIntFromTo `hasNoType` ''SPEC #endif +{-# NOINLINE sourceIntFromThenTo #-} sourceIntFromThenTo :: Int -> IO () sourceIntFromThenTo value = withDrain $ \n -> Stream.enumerateFromThenTo n (n + 1) (n + value) @@ -90,6 +94,7 @@ inspect $ 'sourceIntFromThenTo `hasNoType` ''Fold.Step inspect $ 'sourceIntFromThenTo `hasNoType` ''SPEC #endif +{-# NOINLINE sourceFracFromTo #-} sourceFracFromTo :: Int -> IO () sourceFracFromTo value = withDrain $ \n -> Stream.enumerateFromTo (fromIntegral n :: Double) (fromIntegral (n + value)) @@ -101,6 +106,7 @@ inspect $ 'sourceFracFromTo `hasNoType` ''Fold.Step inspect $ 'sourceFracFromTo `hasNoType` ''SPEC #endif +{-# NOINLINE sourceFracFromThenTo #-} sourceFracFromThenTo :: Int -> IO () sourceFracFromThenTo value = withDrain $ \n -> Stream.enumerateFromThenTo @@ -113,6 +119,7 @@ inspect $ 'sourceFracFromThenTo `hasNoType` ''Fold.Step inspect $ 'sourceFracFromThenTo `hasNoType` ''SPEC #endif +{-# NOINLINE sourceIntegerFromStep #-} sourceIntegerFromStep :: Int -> IO () sourceIntegerFromStep value = withDrain $ \n -> Stream.take value @@ -125,6 +132,7 @@ inspect $ 'sourceIntegerFromStep `hasNoType` ''Fold.Step inspect $ 'sourceIntegerFromStep `hasNoType` ''SPEC #endif +{-# NOINLINE enumerateFrom #-} enumerateFrom :: Int -> IO () enumerateFrom count = withDrain (Stream.take count . Stream.enumerateFrom) @@ -135,11 +143,13 @@ inspect $ 'enumerateFrom `hasNoType` ''Fold.Step inspect $ 'enumerateFrom `hasNoType` ''SPEC #endif +{-# NOINLINE enumerateFromTo #-} enumerateFromTo :: Int -> IO () enumerateFromTo = sourceIntFromTo -- 'enumerateFromTo' is an alias for 'sourceIntFromTo', already covered above. +{-# NOINLINE enumerateFromThen #-} enumerateFromThen :: Int -> IO () enumerateFromThen count = withDrain $ \n -> Stream.take count $ Stream.enumerateFromThen n (n + 1) @@ -151,12 +161,14 @@ inspect $ 'enumerateFromThen `hasNoType` ''Fold.Step inspect $ 'enumerateFromThen `hasNoType` ''SPEC #endif +{-# NOINLINE enumerateFromThenTo #-} enumerateFromThenTo :: Int -> IO () enumerateFromThenTo = sourceIntFromThenTo -- 'enumerateFromThenTo' is an alias for 'sourceIntFromThenTo', already covered above. -- n ~ 1 +{-# NOINLINE enumerate #-} enumerate :: Int -> IO () enumerate count = withDrain $ \n -> Stream.take (count + n) Stream.enumerate :: Stream IO Int @@ -169,6 +181,7 @@ inspect $ 'enumerate `hasNoType` ''SPEC #endif -- n ~ 1 +{-# NOINLINE enumerateTo #-} enumerateTo :: Int -> IO () enumerateTo count = withDrain $ \n -> Stream.enumerateTo (minBound + count + n) @@ -179,6 +192,7 @@ inspect $ 'enumerateTo `hasNoType` ''Fold.Step inspect $ 'enumerateTo `hasNoType` ''SPEC #endif +{-# NOINLINE iterate #-} iterate :: Int -> IO () iterate count = withDrain (Stream.take count . Stream.iterate (+1)) @@ -189,6 +203,7 @@ inspect $ 'iterate `hasNoType` ''Fold.Step inspect $ 'iterate `hasNoType` ''SPEC #endif +{-# NOINLINE iterateM #-} iterateM :: Int -> IO () iterateM count = withDrain (Stream.take count . Stream.iterateM (return . (+1)) . return) @@ -200,6 +215,7 @@ inspect $ 'iterateM `hasNoType` ''Fold.Step inspect $ 'iterateM `hasNoType` ''SPEC #endif +{-# NOINLINE repeatM #-} repeatM :: Int -> IO () repeatM count = withDrain (Stream.take count . Stream.repeatM . return) @@ -210,6 +226,7 @@ inspect $ 'repeatM `hasNoType` ''Fold.Step inspect $ 'repeatM `hasNoType` ''SPEC #endif +{-# NOINLINE replicateM #-} replicateM :: Int -> IO () replicateM count = withDrain (Stream.replicateM count . return) @@ -220,6 +237,7 @@ inspect $ 'replicateM `hasNoType` ''Fold.Step inspect $ 'replicateM `hasNoType` ''SPEC #endif +{-# NOINLINE fromIndices #-} fromIndices :: Int -> IO () fromIndices value = withDrain $ \n -> Stream.take value $ Stream.fromIndices (+ n) @@ -230,6 +248,7 @@ inspect $ 'fromIndices `hasNoType` ''Fold.Step inspect $ 'fromIndices `hasNoType` ''SPEC #endif +{-# NOINLINE fromIndicesM #-} fromIndicesM :: Int -> IO () fromIndicesM value = withDrain $ \n -> Stream.take value $ Stream.fromIndicesM (return <$> (+ n)) diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Lift.hs b/benchmark/Streamly/Benchmark/Data/Stream/Lift.hs index 3055140fac..0cd571d9ad 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Lift.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Lift.hs @@ -69,6 +69,7 @@ withState value n = Stream.evalStateT (return (0 :: Int)) (Stream.liftInner (sourceUnfoldrM value n)) +{-# NOINLINE evalStateTIO #-} evalStateTIO :: Int -> IO () evalStateTIO value = withRandomIntIO $ \n -> Stream.fold Fold.drain (evalStateT value n :: Stream IO Int) @@ -80,6 +81,7 @@ inspect $ 'evalStateTIO `hasNoType` ''Fold.Step inspect $ 'evalStateTIO `hasNoType` ''SPEC #endif +{-# NOINLINE withStateIO #-} withStateIO :: Int -> IO () withStateIO value = withRandomIntIO $ \n -> Stream.fold Fold.drain (withState value n :: Stream IO Int) @@ -91,6 +93,7 @@ inspect $ 'withStateIO `hasNoType` ''Fold.Step inspect $ 'withStateIO `hasNoType` ''SPEC #endif +{-# NOINLINE generalizeInner #-} generalizeInner :: Int -> IO Int generalizeInner value = withPureStream value $ @@ -103,6 +106,7 @@ inspect $ 'generalizeInner `hasNoType` ''Fold.Step inspect $ 'generalizeInner `hasNoType` ''SPEC #endif +{-# NOINLINE generalizeInnerIO #-} generalizeInnerIO :: Int -> IO Int generalizeInnerIO value = withRandomIntIO $ \n -> Stream.fold Fold.length diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Nesting/Basic.hs b/benchmark/Streamly/Benchmark/Data/Stream/Nesting/Basic.hs index 3d61ea454e..23b94a0c3c 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Nesting/Basic.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Nesting/Basic.hs @@ -45,6 +45,7 @@ import Prelude hiding (concatMap, zipWith) -- Appending ------------------------------------------------------------------------------- +{-# NOINLINE interleave2 #-} interleave2 :: Int -> IO () interleave2 count = withRandomIntIO $ \n -> drain $ @@ -60,6 +61,7 @@ inspect $ 'interleave2 `hasNoType` ''S.Step inspect $ 'interleave2 `hasNoType` ''Fold.Step #endif +{-# NOINLINE roundRobin2 #-} roundRobin2 :: Int -> IO () roundRobin2 count = withRandomIntIO $ \n -> S.drain $ @@ -79,6 +81,7 @@ inspect $ 'roundRobin2 `hasNoType` ''Fold.Step -- Merging ------------------------------------------------------------------------------- +{-# NOINLINE mergeBy #-} mergeBy :: Int -> IO () mergeBy count = withRandomIntIO $ \n -> Stream.drain @@ -94,6 +97,7 @@ inspect $ 'mergeBy `hasNoType` ''SPEC inspect $ 'mergeBy `hasNoType` ''Fold.Step #endif +{-# NOINLINE mergeByM #-} mergeByM :: Int -> IO () mergeByM count = withRandomIntIO $ \n -> Stream.drain @@ -128,6 +132,7 @@ sourceUnfoldrMUF count = UF.unfoldrM step then Nothing else Just (cnt, (cnt + 1, start)) +{-# NOINLINE bfsUnfoldEach #-} bfsUnfoldEach :: Int -> Int -> IO () bfsUnfoldEach outer inner = withRandomIntIO $ \n -> S.drain $ S.bfsUnfoldEach @@ -142,6 +147,7 @@ inspect $ 'bfsUnfoldEach `hasNoType` ''Fold.Step inspect $ 'bfsUnfoldEach `hasNoType` ''SPEC #endif +{-# NOINLINE altBfsUnfoldEach #-} altBfsUnfoldEach :: Int -> Int -> IO () altBfsUnfoldEach outer inner = withRandomIntIO $ \n -> S.drain $ S.altBfsUnfoldEach @@ -156,6 +162,7 @@ inspect $ 'altBfsUnfoldEach `hasNoType` ''Fold.Step -- inspect $ 'altBfsUnfoldEach `hasNoType` ''SPEC #endif +{-# NOINLINE unfoldSched #-} unfoldSched :: Int -> Int -> IO () unfoldSched outer inner = withRandomIntIO $ \n -> S.drain $ S.unfoldSched diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Nesting/LogicConcat.hs b/benchmark/Streamly/Benchmark/Data/Stream/Nesting/LogicConcat.hs index 4fdc74aa39..46c4044cd8 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Nesting/LogicConcat.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Nesting/LogicConcat.hs @@ -78,22 +78,27 @@ _schedForEqn maxVal input = Stream.schedForM input $ \y -> do return $ Type.checkStream maxVal x y +{-# NOINLINE fairConcatForBounded #-} fairConcatForBounded :: Int -> IO () fairConcatForBounded maxVal = withRandomIntIO $ \n -> fairConcatForEqn maxVal (Type.boundedInts maxVal n) +{-# NOINLINE fairConcatForKBounded #-} fairConcatForKBounded :: Int -> IO () fairConcatForKBounded maxVal = withRandomIntIO $ \n -> fairConcatForEqnK maxVal (Type.boundedInts maxVal n) +{-# NOINLINE fairConcatForInfinite #-} fairConcatForInfinite :: Int -> IO () fairConcatForInfinite maxVal = withRandomIntIO $ \n -> fairConcatForEqn maxVal (Type.infiniteInts maxVal n) +{-# NOINLINE fairSchedForBounded #-} fairSchedForBounded :: Int -> IO () fairSchedForBounded maxVal = withRandomIntIO $ \n -> fairSchedForEqn maxVal (Type.boundedInts maxVal n) +{-# NOINLINE fairSchedForInfinite #-} fairSchedForInfinite :: Int -> IO () fairSchedForInfinite maxVal = withRandomIntIO $ \n -> fairSchedForEqn maxVal (Type.infiniteInts maxVal n) diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Nesting/LogicUnfold.hs b/benchmark/Streamly/Benchmark/Data/Stream/Nesting/LogicUnfold.hs index 704f0b9ce1..24270b3560 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Nesting/LogicUnfold.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Nesting/LogicUnfold.hs @@ -75,28 +75,35 @@ fairUnfoldSchedEqn maxVal input ints = unfoldCrossBounded :: Int -> IO () unfoldCrossBounded maxVal = unfoldCrossEqn maxVal (Type.boundedIntsUnfold maxVal 0) +{-# NOINLINE fairUnfoldCrossBounded #-} fairUnfoldCrossBounded :: Int -> IO () fairUnfoldCrossBounded maxVal = fairUnfoldCrossEqn maxVal (Type.boundedIntsUnfold maxVal 0) +{-# NOINLINE fairUnfoldCrossInfinite #-} fairUnfoldCrossInfinite :: Int -> IO () fairUnfoldCrossInfinite maxVal = fairUnfoldCrossEqn maxVal (infiniteIntsUnfold maxVal 0) +{-# NOINLINE fairUnfoldEachBounded #-} fairUnfoldEachBounded :: Int -> IO () fairUnfoldEachBounded maxVal = withRandomIntIO $ \n -> fairUnfoldEachEqn maxVal (Type.boundedIntsUnfold maxVal 0) (Type.boundedInts maxVal n) +{-# NOINLINE fairUnfoldEachInfinite #-} fairUnfoldEachInfinite :: Int -> IO () fairUnfoldEachInfinite maxVal = withRandomIntIO $ \n -> fairUnfoldEachEqn maxVal (infiniteIntsUnfold maxVal 0) (Type.infiniteInts maxVal n) +{-# NOINLINE unfoldSchedBounded #-} unfoldSchedBounded :: Int -> IO () unfoldSchedBounded maxVal = withRandomIntIO $ \n -> unfoldSchedEqn maxVal (Type.boundedIntsUnfold maxVal 0) (Type.boundedInts maxVal n) +{-# NOINLINE fairUnfoldSchedBounded #-} fairUnfoldSchedBounded :: Int -> IO () fairUnfoldSchedBounded maxVal = withRandomIntIO $ \n -> fairUnfoldSchedEqn maxVal (Type.boundedIntsUnfold maxVal 0) (Type.boundedInts maxVal n) +{-# NOINLINE fairUnfoldSchedInfinite #-} fairUnfoldSchedInfinite :: Int -> IO () fairUnfoldSchedInfinite maxVal = withRandomIntIO $ \n -> fairUnfoldSchedEqn maxVal (infiniteIntsUnfold maxVal 0) (Type.infiniteInts maxVal n) diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Parse/Group.hs b/benchmark/Streamly/Benchmark/Data/Stream/Parse/Group.hs index 5fcde8fc4a..efc51028c2 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Parse/Group.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Parse/Group.hs @@ -39,6 +39,7 @@ import Stream.Type (benchIO, withStream) -- Grouping transformations ------------------------------------------------------------------------------- +{-# NOINLINE groups #-} groups :: Int -> IO () groups value = withStream value $ Common.drain . S.groupsWhile (==) FL.drain @@ -49,6 +50,7 @@ inspect $ 'groups `hasNoType` ''FL.Step inspect $ 'groups `hasNoType` ''SPEC #endif +{-# NOINLINE groupsWhileLT #-} groupsWhileLT :: Int -> IO () groupsWhileLT value = withStream value $ Common.drain . S.groupsWhile (<) FL.drain @@ -59,6 +61,7 @@ inspect $ 'groupsWhileLT `hasNoType` ''FL.Step inspect $ 'groupsWhileLT `hasNoType` ''SPEC #endif +{-# NOINLINE groupsWhileEq #-} groupsWhileEq :: Int -> IO () groupsWhileEq value = withStream value $ Common.drain . S.groupsWhile (==) FL.drain @@ -69,6 +72,7 @@ inspect $ 'groupsWhileEq `hasNoType` ''FL.Step inspect $ 'groupsWhileEq `hasNoType` ''SPEC #endif +{-# NOINLINE groupsByRollingLT #-} groupsByRollingLT :: Int -> IO () groupsByRollingLT value = withStream value $ Common.drain . S.groupsRollingBy (<) FL.drain @@ -80,6 +84,7 @@ inspect $ 'groupsByRollingLT `hasNoType` ''FL.Step inspect $ 'groupsByRollingLT `hasNoType` ''SPEC #endif +{-# NOINLINE groupsByRollingEq #-} groupsByRollingEq :: Int -> IO () groupsByRollingEq value = withStream value $ Common.drain . S.groupsRollingBy (==) FL.drain @@ -91,6 +96,7 @@ inspect $ 'groupsByRollingEq `hasNoType` ''FL.Step inspect $ 'groupsByRollingEq `hasNoType` ''SPEC #endif +{-# NOINLINE foldIterateM #-} foldIterateM :: Int -> IO () foldIterateM value = withStream value $ diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Prelude/Exceptions.hs b/benchmark/Streamly/Benchmark/Data/Stream/Prelude/Exceptions.hs index 2b199205cc..04f65a8317 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Prelude/Exceptions.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Prelude/Exceptions.hs @@ -21,13 +21,15 @@ module Main (main) where +import Control.DeepSeq (NFData) import Control.Exception (Exception, throwIO) import Data.HashMap.Strict (HashMap) import Data.Proxy (Proxy(..)) -import Stream.Common (drain, benchIOSink) +import Stream.Common (drain) import Streamly.Internal.Data.IsMap.HashMap () import Streamly.Internal.Data.Stream (Stream) import System.IO (Handle, hClose, hPutChar) +import System.Random (randomRIO) import qualified Data.IORef as Ref import qualified Data.Map.Strict as Map @@ -60,6 +62,7 @@ data BenchException instance Exception BenchException +{-# NOINLINE retryNoneSimple #-} retryNoneSimple :: Int -> Int -> IO () retryNoneSimple length from = drain @@ -72,6 +75,7 @@ retryNoneSimple length from = source = Stream.enumerateFromTo from (from + length) +{-# NOINLINE retryNone #-} retryNone :: Int -> Int -> IO () retryNone length from = do ref <- Ref.newIORef (0 :: Int) @@ -85,6 +89,7 @@ retryNone length from = do Stream.replicateM (from + length) $ Ref.modifyIORef' ref (+ 1) >> Ref.readIORef ref +{-# NOINLINE retryAll #-} retryAll :: Int -> Int -> IO () retryAll length from = do ref <- Ref.newIORef 0 @@ -104,6 +109,7 @@ retryAll length from = do then return length else throwIO BenchException1 +{-# NOINLINE retryUnknown #-} retryUnknown :: Int -> Int -> IO () retryUnknown length from = do drain @@ -129,17 +135,20 @@ o_1_space_serial_exceptions length = -- copy stream exceptions ------------------------------------------------------------------------------- +{-# NOINLINE readWriteFinallyStream #-} readWriteFinallyStream :: Handle -> Handle -> IO () readWriteFinallyStream inh devNull = let readEx = Stream.finally (hClose inh) (Stream.unfold FH.reader inh) in Stream.fold (FH.write devNull) readEx +{-# NOINLINE fromToBytesBracketStream #-} fromToBytesBracketStream :: Handle -> Handle -> IO () fromToBytesBracketStream inh devNull = let readEx = Stream.bracket (return ()) (\_ -> hClose inh) (\_ -> IFH.read inh) in IFH.putBytes devNull readEx +{-# NOINLINE readWriteBeforeAfterStream #-} readWriteBeforeAfterStream :: Handle -> Handle -> IO () readWriteBeforeAfterStream inh devNull = let readEx = @@ -151,6 +160,7 @@ readWriteBeforeAfterStream inh devNull = inspect $ 'readWriteBeforeAfterStream `hasNoType` ''Stream.Step #endif +{-# NOINLINE readWriteAfterStream #-} readWriteAfterStream :: Handle -> Handle -> IO () readWriteAfterStream inh devNull = let readEx = Stream.after (hClose inh) (Stream.unfold FH.reader inh) @@ -176,6 +186,7 @@ o_1_space_copy_stream_exceptions env = -- Exceptions toChunks ------------------------------------------------------------------------------- +{-# NOINLINE toChunksBracket #-} toChunksBracket :: Handle -> Handle -> IO () toChunksBracket inh devNull = let readEx = Stream.bracket @@ -199,17 +210,25 @@ excBenchmarks env size = ] ] -{-# INLINE pollCounts #-} -pollCounts :: Stream IO Int -> IO () -pollCounts = drain . Stream.parTapCount (const True) f +{-# INLINE benchIO #-} +benchIO :: NFData b => String -> IO b -> Benchmark +benchIO name = bench name . nfIO + +{-# INLINE withStream #-} +withStream :: Int -> (Stream IO Int -> IO b) -> IO b +withStream value f = randomRIO (1, 1 :: Int) >>= f . Common.sourceUnfoldrM value + +{-# NOINLINE pollCounts #-} +pollCounts :: Int -> IO () +pollCounts value = withStream value $ drain . Stream.parTapCount (const True) f where f = Stream.drain . Stream.rollingMap2 (-) . Stream.delayPost 1 -{-# INLINE takeInterval #-} -takeInterval :: Double -> Stream IO Int -> IO () -takeInterval i = drain . Stream.takeInterval i +{-# NOINLINE takeInterval #-} +takeInterval :: Double -> Int -> IO () +takeInterval i value = withStream value $ drain . Stream.takeInterval i -- Inspection testing is disabled for takeInterval -- Enable it when looking at it throughly @@ -219,9 +238,9 @@ takeInterval i = drain . Stream.takeInterval i -- inspect $ 'takeInterval `hasNoType` ''D.Step #endif -{-# INLINE dropInterval #-} -dropInterval :: Double -> Stream IO Int -> IO () -dropInterval i = drain . Stream.dropInterval i +{-# NOINLINE dropInterval #-} +dropInterval :: Double -> Int -> IO () +dropInterval i value = withStream value $ drain . Stream.dropInterval i -- Inspection testing is disabled for dropInterval -- Enable it when looking at it throughly @@ -237,53 +256,67 @@ _intervalsOfSum i = drain . Stream.intervalsOf i Fold.sum timeBenchmarks :: BenchEnv -> Int -> [Benchmark] timeBenchmarks _env size = - [ benchIOSink size "parTapCount 1 second" pollCounts - , benchIOSink size "takeInterval-all" (takeInterval 10000) - , benchIOSink size "dropInterval-all" (dropInterval 10000) + [ benchIO "parTapCount 1 second" (pollCounts size) + , benchIO "takeInterval-all" (takeInterval 10000 size) + , benchIO "dropInterval-all" (dropInterval 10000 size) ] ------------------------------------------------------------------------------- -- Grouping/Splitting ------------------------------------------------------------------------------- +{-# INLINE getKey #-} +getKey :: Int -> Int -> Int +getKey n = (`mod` n) + {-# INLINE classifySessionsOf #-} -classifySessionsOf :: Stream.MonadAsync m => (Int -> Int) -> Stream m Int -> m () -classifySessionsOf getKey = +classifySessionsOf :: (Int -> Int) -> Int -> IO () +classifySessionsOf getKeyF value = withStream value $ Common.drain . Stream.classifySessionsOf (const (return False)) 3 (Fold.take 10 Fold.sum) . Stream.timestamped - . fmap (\x -> (getKey x, x)) + . fmap (\x -> (getKeyF x, x)) + +{-# NOINLINE classifySessionsOf10k #-} +classifySessionsOf10k :: Int -> IO () +classifySessionsOf10k = classifySessionsOf (getKey 10000) + +{-# NOINLINE classifySessionsOf64 #-} +classifySessionsOf64 :: Int -> IO () +classifySessionsOf64 = classifySessionsOf (getKey 64) {-# INLINE classifySessionsOfHash #-} -classifySessionsOfHash :: Stream.MonadAsync m => - (Int -> Int) -> Stream m Int -> m () -classifySessionsOfHash getKey = +classifySessionsOfHash :: (Int -> Int) -> Int -> IO () +classifySessionsOfHash getKeyF value = withStream value $ Common.drain . Stream.classifySessionsByGeneric (Proxy :: Proxy (HashMap k)) 1 False (const (return False)) 3 (Fold.take 10 Fold.sum) . Stream.timestamped - . fmap (\x -> (getKey x, x)) + . fmap (\x -> (getKeyF x, x)) + +{-# NOINLINE classifySessionsOfHash10k #-} +classifySessionsOfHash10k :: Int -> IO () +classifySessionsOfHash10k = classifySessionsOfHash (getKey 10000) + +{-# NOINLINE classifySessionsOfHash64 #-} +classifySessionsOfHash64 :: Int -> IO () +classifySessionsOfHash64 = classifySessionsOfHash (getKey 64) o_1_space_grouping :: BenchEnv -> Int -> [Benchmark] o_1_space_grouping _env value = -- Buffering operations using heap proportional to group/window sizes. - [ benchIOSink value "classifySessionsOf (10000 buckets)" - (classifySessionsOf (getKey 10000)) - , benchIOSink value "classifySessionsOf (64 buckets)" - (classifySessionsOf (getKey 64)) - , benchIOSink value "classifySessionsOfHash (10000 buckets)" - (classifySessionsOfHash (getKey 10000)) - , benchIOSink value "classifySessionsOfHash (64 buckets)" - (classifySessionsOfHash (getKey 64)) + [ benchIO "classifySessionsOf (10000 buckets)" + (classifySessionsOf10k value) + , benchIO "classifySessionsOf (64 buckets)" + (classifySessionsOf64 value) + , benchIO "classifySessionsOfHash (10000 buckets)" + (classifySessionsOfHash10k value) + , benchIO "classifySessionsOfHash (64 buckets)" + (classifySessionsOfHash64 value) ] - where - - getKey :: Int -> Int -> Int - getKey n = (`mod` n) - moduleName :: String moduleName = "Data.Stream.Prelude" diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Transform/Basic.hs b/benchmark/Streamly/Benchmark/Data/Stream/Transform/Basic.hs index 6885f13a84..b0265e1cd2 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Transform/Basic.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Transform/Basic.hs @@ -61,6 +61,7 @@ import Prelude hiding (sequence, mapM, reverse) scanl' :: MonadIO m => Int -> Stream m Int -> m () scanl' n = composeN n $ Stream.scanl' (+) 0 +{-# NOINLINE scanl'1 #-} scanl'1 :: Int -> IO () scanl'1 value = withStream value (scanl' 1) @@ -69,6 +70,7 @@ inspect $ hasNoTypeClasses 'scanl'1 inspect $ 'scanl'1 `hasNoType` ''Stream.Step #endif +{-# NOINLINE scanl'4 #-} scanl'4 :: Int -> IO () scanl'4 value = withStream value (scanl' 4) @@ -81,6 +83,7 @@ inspect $ 'scanl'4 `hasNoType` ''Stream.Step scanlM' :: MonadIO m => Int -> Stream m Int -> m () scanlM' n = composeN n $ Stream.scanlM' (\b a -> return $ b + a) (return 0) +{-# NOINLINE scanlM'1 #-} scanlM'1 :: Int -> IO () scanlM'1 value = withStream value (scanlM' 1) @@ -89,6 +92,7 @@ inspect $ hasNoTypeClasses 'scanlM'1 inspect $ 'scanlM'1 `hasNoType` ''Stream.Step #endif +{-# NOINLINE scanlM'4 #-} scanlM'4 :: Int -> IO () scanlM'4 value = withStream value (scanlM' 4) @@ -101,6 +105,7 @@ inspect $ 'scanlM'4 `hasNoType` ''Stream.Step scanl1' :: MonadIO m => Int -> Stream m Int -> m () scanl1' n = composeN n $ Stream.scanl1' (+) +{-# NOINLINE scanl1'1 #-} scanl1'1 :: Int -> IO () scanl1'1 value = withStream value (scanl1' 1) @@ -109,6 +114,7 @@ inspect $ hasNoTypeClasses 'scanl1'1 inspect $ 'scanl1'1 `hasNoType` ''Stream.Step #endif +{-# NOINLINE scanl1'4 #-} scanl1'4 :: Int -> IO () scanl1'4 value = withStream value (scanl1' 4) @@ -121,6 +127,7 @@ inspect $ 'scanl1'4 `hasNoType` ''Stream.Step scanl1M' :: MonadIO m => Int -> Stream m Int -> m () scanl1M' n = composeN n $ Stream.scanl1M' (\b a -> return $ b + a) +{-# NOINLINE scanl1M'1 #-} scanl1M'1 :: Int -> IO () scanl1M'1 value = withStream value (scanl1M' 1) @@ -129,6 +136,7 @@ inspect $ hasNoTypeClasses 'scanl1M'1 inspect $ 'scanl1M'1 `hasNoType` ''Stream.Step #endif +{-# NOINLINE scanl1M'4 #-} scanl1M'4 :: Int -> IO () scanl1M'4 value = withStream value (scanl1M' 4) @@ -141,6 +149,7 @@ inspect $ 'scanl1M'4 `hasNoType` ''Stream.Step scan :: MonadIO m => Int -> Stream m Int -> m () scan n = composeN n $ Stream.scanl Scanl.sum +{-# NOINLINE scan1 #-} scan1 :: Int -> IO () scan1 value = withStream value (scan 1) @@ -152,6 +161,7 @@ inspect $ 'scan1 `hasNoType` ''FL.Step inspect $ 'scan1 `hasNoType` ''SPEC #endif +{-# NOINLINE scan4 #-} scan4 :: Int -> IO () scan4 value = withStream value (scan 4) @@ -167,6 +177,7 @@ inspect $ 'scan4 `hasNoType` ''SPEC postscan :: MonadIO m => Int -> Stream m Int -> m () postscan n = composeN n $ Stream.postscanl Scanl.sum +{-# NOINLINE postscan1 #-} postscan1 :: Int -> IO () postscan1 value = withStream value (postscan 1) @@ -178,6 +189,7 @@ inspect $ 'postscan1 `hasNoType` ''FL.Step inspect $ 'postscan1 `hasNoType` ''SPEC #endif +{-# NOINLINE postscan4 #-} postscan4 :: Int -> IO () postscan4 value = withStream value (postscan 4) @@ -193,6 +205,7 @@ inspect $ 'postscan4 `hasNoType` ''SPEC postscanl' :: MonadIO m => Int -> Stream m Int -> m () postscanl' n = composeN n $ Stream.postscanl' (+) 0 +{-# NOINLINE postscanl'1 #-} postscanl'1 :: Int -> IO () postscanl'1 value = withStream value (postscanl' 1) @@ -201,6 +214,7 @@ inspect $ hasNoTypeClasses 'postscanl'1 inspect $ 'postscanl'1 `hasNoType` ''Stream.Step #endif +{-# NOINLINE postscanl'4 #-} postscanl'4 :: Int -> IO () postscanl'4 value = withStream value (postscanl' 4) @@ -213,6 +227,7 @@ inspect $ hasNoTypeClasses 'postscanl'4 postscanlM' :: MonadIO m => Int -> Stream m Int -> m () postscanlM' n = composeN n $ Stream.postscanlM' (\b a -> return $ b + a) (return 0) +{-# NOINLINE postscanlM'1 #-} postscanlM'1 :: Int -> IO () postscanlM'1 value = withStream value (postscanlM' 1) @@ -221,6 +236,7 @@ inspect $ hasNoTypeClasses 'postscanlM'1 inspect $ 'postscanlM'1 `hasNoType` ''Stream.Step #endif +{-# NOINLINE postscanlM'4 #-} postscanlM'4 :: Int -> IO () postscanlM'4 value = withStream value (postscanlM' 4) @@ -233,6 +249,7 @@ inspect $ 'postscanlM'4 `hasNoType` ''Stream.Step sequence :: MonadAsync m => Stream m (m Int) -> m () sequence = Common.drain . Stream.sequence +{-# NOINLINE sequence1 #-} sequence1 :: Int -> IO () sequence1 value = withRandomIntIO $ sequence . sourceUnfoldrAction value @@ -247,6 +264,7 @@ inspect $ 'sequence1 `hasNoType` ''SPEC tap :: MonadIO m => Int -> Stream m Int -> m () tap n = composeN n $ Stream.tap FL.sum +{-# NOINLINE tap1 #-} tap1 :: Int -> IO () tap1 value = withStream value (tap 1) @@ -277,6 +295,7 @@ foldrTMap n = composeN n $ Stream.foldrT (\x xs -> x + 1 `Stream.cons` xs) Strea trace :: MonadAsync m => Int -> Stream m Int -> m () trace n = composeN n $ Stream.trace return +{-# NOINLINE trace4 #-} trace4 :: Int -> IO () trace4 value = withStream value (trace 4) @@ -295,6 +314,7 @@ inspect $ 'trace4 `hasNoType` ''SPEC filterEven :: MonadIO m => Int -> Stream m Int -> m () filterEven n = composeN n $ Stream.filter even +{-# NOINLINE filterEven1 #-} filterEven1 :: Int -> IO () filterEven1 value = withStream value (filterEven 1) @@ -305,6 +325,7 @@ inspect $ 'filterEven1 `hasNoType` ''FL.Step inspect $ 'filterEven1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterEven4 #-} filterEven4 :: Int -> IO () filterEven4 value = withStream value (filterEven 4) @@ -319,6 +340,7 @@ inspect $ 'filterEven4 `hasNoType` ''SPEC filterAllOut :: MonadIO m => Int -> Int -> Stream m Int -> m () filterAllOut value n = composeN n $ Stream.filter (> (value + 1)) +{-# NOINLINE filterAllOut1 #-} filterAllOut1 :: Int -> IO () filterAllOut1 value = withStream value (filterAllOut value 1) @@ -329,6 +351,7 @@ inspect $ 'filterAllOut1 `hasNoType` ''FL.Step inspect $ 'filterAllOut1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterAllOut4 #-} filterAllOut4 :: Int -> IO () filterAllOut4 value = withStream value (filterAllOut value 4) @@ -343,6 +366,7 @@ inspect $ 'filterAllOut4 `hasNoType` ''SPEC filterAllIn :: MonadIO m => Int -> Int -> Stream m Int -> m () filterAllIn value n = composeN n $ Stream.filter (<= (value + 1)) +{-# NOINLINE filterAllIn1 #-} filterAllIn1 :: Int -> IO () filterAllIn1 value = withStream value (filterAllIn value 1) @@ -353,6 +377,7 @@ inspect $ 'filterAllIn1 `hasNoType` ''FL.Step inspect $ 'filterAllIn1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterAllIn4 #-} filterAllIn4 :: Int -> IO () filterAllIn4 value = withStream value (filterAllIn value 4) @@ -367,6 +392,7 @@ inspect $ 'filterAllIn4 `hasNoType` ''SPEC filterMEven :: MonadIO m => Int -> Stream m Int -> m () filterMEven n = composeN n $ Stream.filterM (return . even) +{-# NOINLINE filterMEven1 #-} filterMEven1 :: Int -> IO () filterMEven1 value = withStream value (filterMEven 1) @@ -377,6 +403,7 @@ inspect $ 'filterMEven1 `hasNoType` ''FL.Step inspect $ 'filterMEven1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterMEven4 #-} filterMEven4 :: Int -> IO () filterMEven4 value = withStream value (filterMEven 4) @@ -391,6 +418,7 @@ inspect $ 'filterMEven4 `hasNoType` ''SPEC filterMAllOut :: MonadIO m => Int -> Int -> Stream m Int -> m () filterMAllOut value n = composeN n $ Stream.filterM (\x -> return $ x > (value + 1)) +{-# NOINLINE filterMAllOut1 #-} filterMAllOut1 :: Int -> IO () filterMAllOut1 value = withStream value (filterMAllOut value 1) @@ -401,6 +429,7 @@ inspect $ 'filterMAllOut1 `hasNoType` ''FL.Step inspect $ 'filterMAllOut1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterMAllOut4 #-} filterMAllOut4 :: Int -> IO () filterMAllOut4 value = withStream value (filterMAllOut value 4) @@ -415,6 +444,7 @@ inspect $ 'filterMAllOut4 `hasNoType` ''SPEC filterMAllIn :: MonadIO m => Int -> Int -> Stream m Int -> m () filterMAllIn value n = composeN n $ Stream.filterM (\x -> return $ x <= (value + 1)) +{-# NOINLINE filterMAllIn1 #-} filterMAllIn1 :: Int -> IO () filterMAllIn1 value = withStream value (filterMAllIn value 1) @@ -425,6 +455,7 @@ inspect $ 'filterMAllIn1 `hasNoType` ''FL.Step inspect $ 'filterMAllIn1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterMAllIn4 #-} filterMAllIn4 :: Int -> IO () filterMAllIn4 value = withStream value (filterMAllIn value 4) @@ -439,6 +470,7 @@ inspect $ 'filterMAllIn4 `hasNoType` ''SPEC dropOne :: MonadIO m => Int -> Stream m Int -> m () dropOne n = composeN n $ Stream.drop 1 +{-# NOINLINE dropOne1 #-} dropOne1 :: Int -> IO () dropOne1 value = withStream value (dropOne 1) @@ -449,6 +481,7 @@ inspect $ 'dropOne1 `hasNoType` ''FL.Step inspect $ 'dropOne1 `hasNoType` ''SPEC #endif +{-# NOINLINE dropOne4 #-} dropOne4 :: Int -> IO () dropOne4 value = withStream value (dropOne 4) @@ -463,6 +496,7 @@ inspect $ 'dropOne4 `hasNoType` ''SPEC dropAll :: MonadIO m => Int -> Int -> Stream m Int -> m () dropAll value n = composeN n $ Stream.drop (value + 1) +{-# NOINLINE dropAll1 #-} dropAll1 :: Int -> IO () dropAll1 value = withStream value (dropAll value 1) @@ -473,6 +507,7 @@ inspect $ 'dropAll1 `hasNoType` ''FL.Step inspect $ 'dropAll1 `hasNoType` ''SPEC #endif +{-# NOINLINE dropAll4 #-} dropAll4 :: Int -> IO () dropAll4 value = withStream value (dropAll value 4) @@ -487,6 +522,7 @@ inspect $ 'dropAll4 `hasNoType` ''SPEC dropWhileTrue :: MonadIO m => Int -> Int -> Stream m Int -> m () dropWhileTrue value n = composeN n $ Stream.dropWhile (<= (value + 1)) +{-# NOINLINE dropWhileTrue1 #-} dropWhileTrue1 :: Int -> IO () dropWhileTrue1 value = withStream value (dropWhileTrue value 1) @@ -498,6 +534,7 @@ inspect $ 'dropWhileTrue1 `hasNoType` ''FL.Step inspect $ 'dropWhileTrue1 `hasNoType` ''SPEC #endif +{-# NOINLINE dropWhileTrue4 #-} dropWhileTrue4 :: Int -> IO () dropWhileTrue4 value = withStream value (dropWhileTrue value 4) @@ -513,6 +550,7 @@ inspect $ 'dropWhileTrue4 `hasNoType` ''SPEC dropWhileMTrue :: MonadIO m => Int -> Int -> Stream m Int -> m () dropWhileMTrue value n = composeN n $ Stream.dropWhileM (return . (<= (value + 1))) +{-# NOINLINE dropWhileMTrue4 #-} dropWhileMTrue4 :: Int -> IO () dropWhileMTrue4 value = withStream value (dropWhileMTrue value 4) @@ -528,6 +566,7 @@ inspect $ 'dropWhileMTrue4 `hasNoType` ''SPEC dropWhileFalse :: MonadIO m => Int -> Int -> Stream m Int -> m () dropWhileFalse value n = composeN n $ Stream.dropWhile (> (value + 1)) +{-# NOINLINE dropWhileFalse1 #-} dropWhileFalse1 :: Int -> IO () dropWhileFalse1 value = withStream value (dropWhileFalse value 1) @@ -539,6 +578,7 @@ inspect $ 'dropWhileFalse1 `hasNoType` ''FL.Step inspect $ 'dropWhileFalse1 `hasNoType` ''SPEC #endif +{-# NOINLINE dropWhileFalse4 #-} dropWhileFalse4 :: Int -> IO () dropWhileFalse4 value = withStream value (dropWhileFalse value 4) @@ -554,6 +594,7 @@ inspect $ 'dropWhileFalse4 `hasNoType` ''SPEC findIndices :: MonadIO m => Int -> Int -> Stream m Int -> m () findIndices value n = composeN n $ Stream.findIndices (== (value + 1)) +{-# NOINLINE findIndices1 #-} findIndices1 :: Int -> IO () findIndices1 value = withStream value (findIndices value 1) @@ -564,6 +605,7 @@ inspect $ 'findIndices1 `hasNoType` ''FL.Step inspect $ 'findIndices1 `hasNoType` ''SPEC #endif +{-# NOINLINE findIndices4 #-} findIndices4 :: Int -> IO () findIndices4 value = withStream value (findIndices value 4) @@ -578,6 +620,7 @@ inspect $ 'findIndices4 `hasNoType` ''SPEC elemIndices :: MonadIO m => Int -> Int -> Stream m Int -> m () elemIndices value n = composeN n $ Stream.elemIndices (value + 1) +{-# NOINLINE elemIndices1 #-} elemIndices1 :: Int -> IO () elemIndices1 value = withStream value (elemIndices value 1) @@ -588,6 +631,7 @@ inspect $ 'elemIndices1 `hasNoType` ''FL.Step inspect $ 'elemIndices1 `hasNoType` ''SPEC #endif +{-# NOINLINE elemIndices4 #-} elemIndices4 :: Int -> IO () elemIndices4 value = withStream value (elemIndices value 4) @@ -598,6 +642,7 @@ inspect $ 'elemIndices4 `hasNoType` ''FL.Step inspect $ 'elemIndices4 `hasNoType` ''SPEC #endif +{-# NOINLINE findIndex #-} findIndex :: Int -> IO (Maybe Int) findIndex value = withStream value (Stream.head . Stream.findIndices (== (value + 1))) @@ -608,6 +653,7 @@ inspect $ 'findIndex `hasNoType` ''FL.Step inspect $ 'findIndex `hasNoType` ''SPEC #endif +{-# NOINLINE elemIndex #-} elemIndex :: Int -> IO (Maybe Int) elemIndex value = withStream value (Stream.head . Stream.elemIndices (value + 1)) @@ -622,6 +668,7 @@ inspect $ 'elemIndex `hasNoType` ''SPEC deleteBy :: MonadIO m => Int -> Int -> Stream m Int -> m () deleteBy value n = composeN n $ Stream.deleteBy (>=) (value + 1) +{-# NOINLINE deleteBy1 #-} deleteBy1 :: Int -> IO () deleteBy1 value = withStream value (deleteBy value 1) @@ -632,6 +679,7 @@ inspect $ 'deleteBy1 `hasNoType` ''FL.Step inspect $ 'deleteBy1 `hasNoType` ''SPEC #endif +{-# NOINLINE deleteBy4 #-} deleteBy4 :: Int -> IO () deleteBy4 value = withStream value (deleteBy value 4) @@ -647,6 +695,7 @@ inspect $ 'deleteBy4 `hasNoType` ''SPEC uniq :: MonadIO m => Int -> Stream m Int -> m () uniq n = composeN n Stream.uniq +{-# NOINLINE uniq1 #-} uniq1 :: Int -> IO () uniq1 value = withStream value (uniq 1) @@ -657,6 +706,7 @@ inspect $ 'uniq1 `hasNoType` ''FL.Step inspect $ 'uniq1 `hasNoType` ''SPEC #endif +{-# NOINLINE uniq4 #-} uniq4 :: Int -> IO () uniq4 value = withStream value (uniq 4) @@ -677,6 +727,7 @@ mapMaybe n = then Nothing else Just x) +{-# NOINLINE mapMaybe1 #-} mapMaybe1 :: Int -> IO () mapMaybe1 value = withStream value (mapMaybe 1) @@ -687,6 +738,7 @@ inspect $ 'mapMaybe1 `hasNoType` ''FL.Step inspect $ 'mapMaybe1 `hasNoType` ''SPEC #endif +{-# NOINLINE mapMaybe4 #-} mapMaybe4 :: Int -> IO () mapMaybe4 value = withStream value (mapMaybe 4) @@ -707,6 +759,7 @@ mapMaybeM n = then return Nothing else return $ Just x) +{-# NOINLINE mapMaybeM1 #-} mapMaybeM1 :: Int -> IO () mapMaybeM1 value = withStream value (mapMaybeM 1) @@ -717,6 +770,7 @@ inspect $ 'mapMaybeM1 `hasNoType` ''FL.Step inspect $ 'mapMaybeM1 `hasNoType` ''SPEC #endif +{-# NOINLINE mapMaybeM4 #-} mapMaybeM4 :: Int -> IO () mapMaybeM4 value = withStream value (mapMaybeM 4) @@ -735,6 +789,7 @@ inspect $ 'mapMaybeM4 `hasNoType` ''SPEC intersperse :: MonadAsync m => Int -> Int -> Stream m Int -> m () intersperse value n = composeN n $ Stream.intersperse (value + 1) +{-# NOINLINE intersperse1 #-} intersperse1 :: Int -> IO () intersperse1 value = withStream value (intersperse value 1) @@ -746,6 +801,7 @@ inspect $ 'intersperse1 `hasNoType` ''FL.Step inspect $ 'intersperse1 `hasNoType` ''SPEC #endif +{-# NOINLINE intersperse4 #-} intersperse4 :: Int -> IO () intersperse4 value = withStream value (intersperse value 4) @@ -761,6 +817,7 @@ inspect $ 'intersperse4 `hasNoType` ''FL.Step intersperseM :: MonadAsync m => Int -> Int -> Stream m Int -> m () intersperseM value n = composeN n $ Stream.intersperseM (return $ value + 1) +{-# NOINLINE intersperseM1 #-} intersperseM1 :: Int -> IO () intersperseM1 value = withStream value (intersperseM value 1) @@ -776,6 +833,7 @@ inspect $ 'intersperseM1 `hasNoType` ''SPEC insertBy :: MonadIO m => Int -> Int -> Stream m Int -> m () insertBy value n = composeN n $ Stream.insertBy compare (value + 1) +{-# NOINLINE insertBy1 #-} insertBy1 :: Int -> IO () insertBy1 value = withStream value (insertBy value 1) @@ -786,6 +844,7 @@ inspect $ 'insertBy1 `hasNoType` ''FL.Step inspect $ 'insertBy1 `hasNoType` ''SPEC #endif +{-# NOINLINE insertBy4 #-} insertBy4 :: Int -> IO () insertBy4 value = withStream value (insertBy value 4) @@ -801,6 +860,7 @@ interposeSuffix :: Monad m => Int -> Int -> Stream m Int -> m () interposeSuffix value n = composeN n $ Stream.unfoldEachSepBy (value + 1) Unfold.identity +{-# NOINLINE interposeSuffix1 #-} interposeSuffix1 :: Int -> IO () interposeSuffix1 value = withStream value (interposeSuffix value 1) @@ -817,6 +877,7 @@ intercalateSuffix :: Monad m => Int -> Int -> Stream m Int -> m () intercalateSuffix value n = composeN n $ Stream.unfoldEachSepBySeq (value + 1) Unfold.identity +{-# NOINLINE intercalateSuffix1 #-} intercalateSuffix1 :: Int -> IO () intercalateSuffix1 value = withStream value (intercalateSuffix value 1) @@ -837,6 +898,7 @@ inspect $ 'intercalateSuffix1 `hasNoType` ''SPEC indexed :: MonadIO m => Int -> Stream m Int -> m () indexed n = composeN n (fmap snd . Stream.indexed) +{-# NOINLINE indexed1 #-} indexed1 :: Int -> IO () indexed1 value = withStream value (indexed 1) @@ -847,6 +909,7 @@ inspect $ 'indexed1 `hasNoType` ''FL.Step inspect $ 'indexed1 `hasNoType` ''SPEC #endif +{-# NOINLINE indexed4 #-} indexed4 :: Int -> IO () indexed4 value = withStream value (indexed 4) @@ -861,6 +924,7 @@ inspect $ 'indexed4 `hasNoType` ''SPEC indexedR :: MonadIO m => Int -> Int -> Stream m Int -> m () indexedR value n = composeN n (fmap snd . Stream.indexedR value) +{-# NOINLINE indexedR1 #-} indexedR1 :: Int -> IO () indexedR1 value = withStream value (indexedR value 1) @@ -871,6 +935,7 @@ inspect $ 'indexedR1 `hasNoType` ''FL.Step inspect $ 'indexedR1 `hasNoType` ''SPEC #endif +{-# NOINLINE indexedR4 #-} indexedR4 :: Int -> IO () indexedR4 value = withStream value (indexedR value 4) @@ -885,6 +950,7 @@ inspect $ 'indexedR4 `hasNoType` ''SPEC -- Size conserving transformations (reordering, buffering, etc.) ------------------------------------------------------------------------------- +{-# NOINLINE reverse #-} reverse :: Int -> IO () reverse value = withStream value (composeN 1 Stream.reverse) @@ -895,6 +961,7 @@ inspect $ 'reverse `hasNoType` ''FL.Step -- inspect $ 'reverse `hasNoType` ''SPEC #endif +{-# NOINLINE reverse' #-} reverse' :: Int -> IO () reverse' value = withStream value (composeN 1 Stream.reverseUnbox) diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Transform/Composed.hs b/benchmark/Streamly/Benchmark/Data/Stream/Transform/Composed.hs index 2148bfba5e..f36a04852c 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Transform/Composed.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Transform/Composed.hs @@ -70,6 +70,7 @@ iterateSource g count len n = f count (sourceUnfoldrM len n) scanMap :: MonadIO m => Int -> Stream m Int -> m () scanMap n = composeN n $ fmap (subtract 1) . Common.scanl' (+) 0 +{-# NOINLINE scanMap1 #-} scanMap1 :: Int -> IO () scanMap1 value = withStream value (scanMap 1) @@ -81,6 +82,7 @@ inspect $ 'scanMap1 `hasNoType` ''FL.Step inspect $ 'scanMap1 `hasNoType` ''SPEC #endif +{-# NOINLINE scanMap2 #-} scanMap2 :: Int -> IO () scanMap2 value = withStream value (scanMap 2) @@ -92,6 +94,7 @@ inspect $ 'scanMap2 `hasNoType` ''FL.Step inspect $ 'scanMap2 `hasNoType` ''SPEC #endif +{-# NOINLINE scanMap4 #-} scanMap4 :: Int -> IO () scanMap4 value = withStream value (scanMap 4) @@ -107,6 +110,7 @@ inspect $ 'scanMap4 `hasNoType` ''SPEC dropMap :: MonadIO m => Int -> Stream m Int -> m () dropMap n = composeN n $ fmap (subtract 1) . S.drop 1 +{-# NOINLINE dropMap1 #-} dropMap1 :: Int -> IO () dropMap1 value = withStream value (dropMap 1) @@ -117,6 +121,7 @@ inspect $ 'dropMap1 `hasNoType` ''FL.Step inspect $ 'dropMap1 `hasNoType` ''SPEC #endif +{-# NOINLINE dropMap2 #-} dropMap2 :: Int -> IO () dropMap2 value = withStream value (dropMap 2) @@ -127,6 +132,7 @@ inspect $ 'dropMap2 `hasNoType` ''FL.Step inspect $ 'dropMap2 `hasNoType` ''SPEC #endif +{-# NOINLINE dropMap4 #-} dropMap4 :: Int -> IO () dropMap4 value = withStream value (dropMap 4) @@ -141,6 +147,7 @@ inspect $ 'dropMap4 `hasNoType` ''SPEC dropScan :: MonadIO m => Int -> Stream m Int -> m () dropScan n = composeN n $ Common.scanl' (+) 0 . S.drop 1 +{-# NOINLINE dropScan1 #-} dropScan1 :: Int -> IO () dropScan1 value = withStream value (dropScan 1) @@ -152,6 +159,7 @@ inspect $ 'dropScan1 `hasNoType` ''FL.Step inspect $ 'dropScan1 `hasNoType` ''SPEC #endif +{-# NOINLINE dropScan2 #-} dropScan2 :: Int -> IO () dropScan2 value = withStream value (dropScan 2) @@ -163,6 +171,7 @@ inspect $ 'dropScan2 `hasNoType` ''FL.Step inspect $ 'dropScan2 `hasNoType` ''SPEC #endif +{-# NOINLINE dropScan4 #-} dropScan4 :: Int -> IO () dropScan4 value = withStream value (dropScan 4) @@ -178,6 +187,7 @@ inspect $ 'dropScan4 `hasNoType` ''SPEC takeDrop :: MonadIO m => Int -> Int -> Stream m Int -> m () takeDrop value n = composeN n $ S.drop 1 . S.take (value + 1) +{-# NOINLINE takeDrop1 #-} takeDrop1 :: Int -> IO () takeDrop1 value = withStream value (takeDrop value 1) @@ -188,6 +198,7 @@ inspect $ 'takeDrop1 `hasNoType` ''FL.Step inspect $ 'takeDrop1 `hasNoType` ''SPEC #endif +{-# NOINLINE takeDrop2 #-} takeDrop2 :: Int -> IO () takeDrop2 value = withStream value (takeDrop value 2) @@ -198,6 +209,7 @@ inspect $ 'takeDrop2 `hasNoType` ''FL.Step inspect $ 'takeDrop2 `hasNoType` ''SPEC #endif +{-# NOINLINE takeDrop4 #-} takeDrop4 :: Int -> IO () takeDrop4 value = withStream value (takeDrop value 4) @@ -212,6 +224,7 @@ inspect $ 'takeDrop4 `hasNoType` ''SPEC takeScan :: MonadIO m => Int -> Int -> Stream m Int -> m () takeScan value n = composeN n $ Common.scanl' (+) 0 . S.take (value + 1) +{-# NOINLINE takeScan1 #-} takeScan1 :: Int -> IO () takeScan1 value = withStream value (takeScan value 1) @@ -223,6 +236,7 @@ inspect $ 'takeScan1 `hasNoType` ''FL.Step inspect $ 'takeScan1 `hasNoType` ''SPEC #endif +{-# NOINLINE takeScan2 #-} takeScan2 :: Int -> IO () takeScan2 value = withStream value (takeScan value 2) @@ -234,6 +248,7 @@ inspect $ 'takeScan2 `hasNoType` ''FL.Step inspect $ 'takeScan2 `hasNoType` ''SPEC #endif +{-# NOINLINE takeScan4 #-} takeScan4 :: Int -> IO () takeScan4 value = withStream value (takeScan value 4) @@ -249,6 +264,7 @@ inspect $ 'takeScan4 `hasNoType` ''SPEC takeMap :: MonadIO m => Int -> Int -> Stream m Int -> m () takeMap value n = composeN n $ fmap (subtract 1) . S.take (value + 1) +{-# NOINLINE takeMap1 #-} takeMap1 :: Int -> IO () takeMap1 value = withStream value (takeMap value 1) @@ -259,6 +275,7 @@ inspect $ 'takeMap1 `hasNoType` ''FL.Step inspect $ 'takeMap1 `hasNoType` ''SPEC #endif +{-# NOINLINE takeMap2 #-} takeMap2 :: Int -> IO () takeMap2 value = withStream value (takeMap value 2) @@ -269,6 +286,7 @@ inspect $ 'takeMap2 `hasNoType` ''FL.Step inspect $ 'takeMap2 `hasNoType` ''SPEC #endif +{-# NOINLINE takeMap4 #-} takeMap4 :: Int -> IO () takeMap4 value = withStream value (takeMap value 4) @@ -283,6 +301,7 @@ inspect $ 'takeMap4 `hasNoType` ''SPEC filterDrop :: MonadIO m => Int -> Int -> Stream m Int -> m () filterDrop value n = composeN n $ S.drop 1 . S.filter (<= (value + 1)) +{-# NOINLINE filterDrop1 #-} filterDrop1 :: Int -> IO () filterDrop1 value = withStream value (filterDrop value 1) @@ -293,6 +312,7 @@ inspect $ 'filterDrop1 `hasNoType` ''FL.Step inspect $ 'filterDrop1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterDrop2 #-} filterDrop2 :: Int -> IO () filterDrop2 value = withStream value (filterDrop value 2) @@ -303,6 +323,7 @@ inspect $ 'filterDrop2 `hasNoType` ''FL.Step inspect $ 'filterDrop2 `hasNoType` ''SPEC #endif +{-# NOINLINE filterDrop4 #-} filterDrop4 :: Int -> IO () filterDrop4 value = withStream value (filterDrop value 4) @@ -317,6 +338,7 @@ inspect $ 'filterDrop4 `hasNoType` ''SPEC filterTake :: MonadIO m => Int -> Int -> Stream m Int -> m () filterTake value n = composeN n $ S.take (value + 1) . S.filter (<= (value + 1)) +{-# NOINLINE filterTake1 #-} filterTake1 :: Int -> IO () filterTake1 value = withStream value (filterTake value 1) @@ -327,6 +349,7 @@ inspect $ 'filterTake1 `hasNoType` ''FL.Step inspect $ 'filterTake1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterTake2 #-} filterTake2 :: Int -> IO () filterTake2 value = withStream value (filterTake value 2) @@ -337,6 +360,7 @@ inspect $ 'filterTake2 `hasNoType` ''FL.Step inspect $ 'filterTake2 `hasNoType` ''SPEC #endif +{-# NOINLINE filterTake4 #-} filterTake4 :: Int -> IO () filterTake4 value = withStream value (filterTake value 4) @@ -351,6 +375,7 @@ inspect $ 'filterTake4 `hasNoType` ''SPEC filterScan :: MonadIO m => Int -> Stream m Int -> m () filterScan n = composeN n $ Common.scanl' (+) 0 . S.filter (<= maxBound) +{-# NOINLINE filterScan1 #-} filterScan1 :: Int -> IO () filterScan1 value = withStream value (filterScan 1) @@ -362,6 +387,7 @@ inspect $ 'filterScan1 `hasNoType` ''FL.Step inspect $ 'filterScan1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterScan2 #-} filterScan2 :: Int -> IO () filterScan2 value = withStream value (filterScan 2) @@ -373,6 +399,7 @@ inspect $ 'filterScan2 `hasNoType` ''FL.Step inspect $ 'filterScan2 `hasNoType` ''SPEC #endif +{-# NOINLINE filterScan4 #-} filterScan4 :: Int -> IO () filterScan4 value = withStream value (filterScan 4) @@ -388,6 +415,7 @@ inspect $ 'filterScan4 `hasNoType` ''SPEC filterScanl1 :: MonadIO m => Int -> Stream m Int -> m () filterScanl1 n = composeN n $ S.scanl1' (+) . S.filter (<= maxBound) +{-# NOINLINE filterScanl12 #-} filterScanl12 :: Int -> IO () filterScanl12 value = withStream value (filterScanl1 2) @@ -399,6 +427,7 @@ inspect $ 'filterScanl12 `hasNoType` ''FL.Step inspect $ 'filterScanl12 `hasNoType` ''SPEC #endif +{-# NOINLINE filterScanl14 #-} filterScanl14 :: Int -> IO () filterScanl14 value = withStream value (filterScanl1 4) @@ -414,6 +443,7 @@ inspect $ 'filterScanl14 `hasNoType` ''SPEC filterMap :: MonadIO m => Int -> Int -> Stream m Int -> m () filterMap value n = composeN n $ fmap (subtract 1) . S.filter (<= (value + 1)) +{-# NOINLINE filterMap1 #-} filterMap1 :: Int -> IO () filterMap1 value = withStream value (filterMap value 1) @@ -424,6 +454,7 @@ inspect $ 'filterMap1 `hasNoType` ''FL.Step inspect $ 'filterMap1 `hasNoType` ''SPEC #endif +{-# NOINLINE filterMap2 #-} filterMap2 :: Int -> IO () filterMap2 value = withStream value (filterMap value 2) @@ -434,6 +465,7 @@ inspect $ 'filterMap2 `hasNoType` ''FL.Step inspect $ 'filterMap2 `hasNoType` ''SPEC #endif +{-# NOINLINE filterMap4 #-} filterMap4 :: Int -> IO () filterMap4 value = withStream value (filterMap value 4) @@ -452,6 +484,7 @@ data Pair a b = Pair !a !b deriving (Generic, NFData) +{-# NOINLINE sumProductFold #-} sumProductFold :: Int -> IO (Pair Int Int) sumProductFold value = withStream value $ @@ -464,6 +497,7 @@ inspect $ 'sumProductFold `hasNoType` ''FL.Step inspect $ 'sumProductFold `hasNoType` ''SPEC #endif +{-# NOINLINE sumProductScan #-} sumProductScan :: Int -> IO (Pair Int Int) sumProductScan value = withStream value $ @@ -478,6 +512,7 @@ inspect $ 'sumProductScan `hasNoType` ''FL.Step inspect $ 'sumProductScan `hasNoType` ''SPEC #endif +{-# NOINLINE foldl'ReduceMap #-} foldl'ReduceMap :: Int -> IO Int foldl'ReduceMap value = withStream value $ fmap (+ 1) . Common.foldl' (+) 0 @@ -493,32 +528,39 @@ inspect $ 'foldl'ReduceMap `hasNoType` ''SPEC ------------------------------------------------------------------------------- -- this is quadratic +{-# NOINLINE iterateScan #-} iterateScan :: Int -> Int -> IO () iterateScan value iterCount = withRandomIntIO $ Common.drain . iterateSource (Common.scanl' (+) 0) (value `div` iterCount) iterCount -- this is quadratic +{-# NOINLINE iterateScanl1 #-} iterateScanl1 :: Int -> Int -> IO () iterateScanl1 value iterCount = withRandomIntIO $ Common.drain . iterateSource (S.scanl1' (+)) (value `div` iterCount) iterCount +{-# NOINLINE iterateMapM #-} iterateMapM :: Int -> Int -> IO () iterateMapM value iterCount = withRandomIntIO $ Common.drain . iterateSource (S.mapM return) (value `div` iterCount) iterCount +{-# NOINLINE iterateFilterEven #-} iterateFilterEven :: Int -> Int -> IO () iterateFilterEven value iterCount = withRandomIntIO $ Common.drain . iterateSource (S.filter even) (value `div` iterCount) iterCount +{-# NOINLINE iterateTakeAll #-} iterateTakeAll :: Int -> Int -> IO () iterateTakeAll value iterCount = withRandomIntIO $ Common.drain . iterateSource (S.take (value + 1)) (value `div` iterCount) iterCount +{-# NOINLINE iterateDropOne #-} iterateDropOne :: Int -> Int -> IO () iterateDropOne value iterCount = withRandomIntIO $ Common.drain . iterateSource (S.drop 1) (value `div` iterCount) iterCount +{-# NOINLINE iterateDropWhileTrue #-} iterateDropWhileTrue :: Int -> Int -> IO () iterateDropWhileTrue value iterCount = withRandomIntIO @@ -567,14 +609,17 @@ _iterateSingleton :: _iterateSingleton g value n = S.foldrM g (return n) $ sourceIntFromTo value n -} +{-# NOINLINE iteratePlusBaseline #-} iteratePlusBaseline :: Int -> IO Int iteratePlusBaseline value = withRandomIntIO $ \i0 -> iterateN (\i acc -> acc >>= \n -> return $ i + n) (return i0) value +{-# NOINLINE iterateSubMap #-} iterateSubMap :: Int -> IO () iterateSubMap value = withRandomIntIO $ drain . iterateSingleton (<$) value +{-# NOINLINE iterateFmap #-} iterateFmap :: Int -> IO () iterateFmap value = withRandomIntIO $ drain . iterateSingleton (fmap . (+)) value @@ -593,6 +638,7 @@ sieveScan = then (primes ++ [n], Just n) else (primes, Nothing)) (return ([2], Just 2))) +{-# NOINLINE naivePrimeSieve #-} naivePrimeSieve :: Int -> IO Int naivePrimeSieve value = withRandomIntIO $ \n -> diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Type/Basic.hs b/benchmark/Streamly/Benchmark/Data/Stream/Type/Basic.hs index 67de33611e..eb50fccba2 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Type/Basic.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Type/Basic.hs @@ -94,6 +94,7 @@ withPureStream value f = randomRIO (1, 1) <&> (f . sourceUnfoldr value) -- fromList ------------------------------------------------------------------------------- +{-# NOINLINE sourceFromList #-} sourceFromList :: Int -> IO () sourceFromList value = withDrain $ \n -> Stream.fromList [n..n+value] @@ -108,6 +109,7 @@ inspect $ 'sourceFromList `hasNoType` ''SPEC -- elements we generate value/2 tuples and reduce each tuple's 'fromTuple' -- stream with a light 'sum' fold (avoiding a heavy, non-fusible 'concatMap' -- that would mask the cost of 'fromTuple'). +{-# NOINLINE sourceFromTuple #-} sourceFromTuple :: Int -> IO () sourceFromTuple value = withDrain $ \n -> Stream.mapM (Stream.fold Fold.sum . Stream.fromTuple) @@ -121,6 +123,7 @@ inspect $ 'sourceFromTuple `hasNoType` ''Fold.Step inspect $ 'sourceFromTuple `hasNoType` ''SPEC #endif +{-# NOINLINE sourceIsList #-} sourceIsList :: Int -> IO () sourceIsList value = withDrainPure $ \n -> GHC.fromList [n..n+value] @@ -131,6 +134,7 @@ inspect $ 'sourceIsList `hasNoType` ''Fold.Step inspect $ 'sourceIsList `hasNoType` ''SPEC #endif +{-# NOINLINE sourceIsString #-} sourceIsString :: Int -> IO () sourceIsString value = withDrainPure $ \n -> GHC.fromString (Prelude.replicate (n + value) 'a') @@ -431,6 +435,7 @@ _foldableMsum value n = -- Show instance ------------------------------------------------------------------------------- +{-# NOINLINE showInstance #-} showInstance :: Int -> IO String showInstance value = withPureStream value show @@ -442,6 +447,7 @@ showInstanceList = show -- Eq and Ord instances ------------------------------------------------------------------------------- +{-# NOINLINE eqInstance #-} eqInstance :: Int -> IO Bool eqInstance value = withPureStream value $ \src -> src == src @@ -452,6 +458,7 @@ inspect $ 'eqInstance `hasNoType` ''Fold.Step inspect $ 'eqInstance `hasNoType` ''SPEC #endif +{-# NOINLINE eqInstanceNotEq #-} eqInstanceNotEq :: Int -> IO Bool eqInstanceNotEq value = withPureStream value $ \src -> src /= src @@ -462,6 +469,7 @@ inspect $ 'eqInstanceNotEq `hasNoType` ''Fold.Step inspect $ 'eqInstanceNotEq `hasNoType` ''SPEC #endif +{-# NOINLINE ordInstance #-} ordInstance :: Int -> IO Bool ordInstance value = withPureStream value $ \src -> src < src @@ -476,6 +484,7 @@ inspect $ 'ordInstance `hasNoType` ''SPEC -- Reductions ------------------------------------------------------------------------------- +{-# NOINLINE uncons #-} uncons :: Int -> IO () uncons value = withStream value go @@ -494,6 +503,7 @@ inspect $ 'uncons `hasNoType` ''Fold.Step inspect $ 'uncons `hasNoType` ''SPEC #endif +{-# NOINLINE foldBreak #-} foldBreak :: Int -> IO () foldBreak value = withStream value go @@ -510,6 +520,7 @@ inspect $ 'foldBreak `hasNoType` ''Fold.Step inspect $ 'foldBreak `hasNoType` ''SPEC #endif +{-# NOINLINE foldrMElem #-} foldrMElem :: Int -> IO Bool foldrMElem value = withStream value @@ -524,6 +535,7 @@ inspect $ 'foldrMElem `hasNoType` ''Fold.Step inspect $ 'foldrMElem `hasNoType` ''SPEC #endif +{-# NOINLINE foldrMElemIdentity #-} foldrMElemIdentity :: Int -> IO Bool foldrMElemIdentity value = withPureStream value $ @@ -538,15 +550,18 @@ inspect $ 'foldrMElemIdentity `hasNoType` ''Fold.Step inspect $ 'foldrMElemIdentity `hasNoType` ''SPEC #endif +{-# NOINLINE foldrMToList #-} foldrMToList :: Int -> IO [Int] foldrMToList value = withStream value $ S.foldrM (\x xs -> (x :) <$> xs) (return []) +{-# NOINLINE foldrMToListIdentity #-} foldrMToListIdentity :: Int -> IO [Int] foldrMToListIdentity value = withPureStream value (runIdentity . S.foldrM (\x xs -> (x :) <$> xs) (return [])) +{-# NOINLINE foldl'Reduce #-} foldl'Reduce :: Int -> IO Int foldl'Reduce value = withStream value (S.foldl' (+) 0) @@ -555,6 +570,7 @@ inspect $ hasNoTypeClasses 'foldl'Reduce inspect $ 'foldl'Reduce `hasNoType` ''S.Step #endif +{-# NOINLINE foldl'ReduceIdentity #-} foldl'ReduceIdentity :: Int -> IO Int foldl'ReduceIdentity value = withPureStream value $ runIdentity . S.foldl' (+) 0 @@ -564,6 +580,7 @@ inspect $ hasNoTypeClasses 'foldl'ReduceIdentity inspect $ 'foldl'ReduceIdentity `hasNoType` ''S.Step #endif +{-# NOINLINE foldlM'Reduce #-} foldlM'Reduce :: Int -> IO Int foldlM'Reduce value = withStream value (S.foldlM' (\xs a -> return $ a + xs) (return 0)) @@ -573,6 +590,7 @@ inspect $ hasNoTypeClasses 'foldlM'Reduce inspect $ 'foldlM'Reduce `hasNoType` ''S.Step #endif +{-# NOINLINE foldlM'ReduceIdentity #-} foldlM'ReduceIdentity :: Int -> IO Int foldlM'ReduceIdentity value = withPureStream value $ @@ -583,6 +601,7 @@ inspect $ hasNoTypeClasses 'foldlM'ReduceIdentity inspect $ 'foldlM'ReduceIdentity `hasNoType` ''S.Step #endif +{-# NOINLINE toNull #-} toNull :: Int -> IO () toNull value = withStream value S.drain @@ -593,9 +612,11 @@ inspect $ 'toNull `hasNoType` ''Fold.Step inspect $ 'toNull `hasNoType` ''SPEC #endif +{-# NOINLINE drainPure #-} drainPure :: Int -> IO () drainPure value = withPureStream value $ runIdentity . drain +{-# NOINLINE drainN #-} drainN :: Int -> IO () drainN value = withStream value (S.fold (Fold.drainN value)) @@ -606,34 +627,42 @@ inspect $ 'drainN `hasNoType` ''Fold.Step inspect $ 'drainN `hasNoType` ''SPEC #endif +{-# NOINLINE foldl'Build #-} foldl'Build :: Int -> IO [Int] foldl'Build value = withStream value (S.foldl' (flip (:)) []) +{-# NOINLINE foldl'BuildIdentity #-} foldl'BuildIdentity :: Int -> IO [Int] foldl'BuildIdentity value = withPureStream value (runIdentity . S.foldl' (flip (:)) []) +{-# NOINLINE foldlM'Build #-} foldlM'Build :: Int -> IO [Int] foldlM'Build value = withStream value (S.foldlM' (\xs x -> return $ x : xs) (return [])) +{-# NOINLINE foldlM'BuildIdentity #-} foldlM'BuildIdentity :: Int -> IO [Int] foldlM'BuildIdentity value = withPureStream value (runIdentity . S.foldlM' (\xs x -> return $ x : xs) (return [])) +{-# NOINLINE foldrMToSum #-} foldrMToSum :: Int -> IO Int foldrMToSum value = withStream value (S.foldrM (\x xs -> (x +) <$> xs) (return 0)) +{-# NOINLINE foldrMToSumIdentity #-} foldrMToSumIdentity :: Int -> IO Int foldrMToSumIdentity value = withPureStream value (runIdentity . S.foldrM (\x xs -> (x +) <$> xs) (return 0)) +{-# NOINLINE toList' #-} toList' :: Int -> IO [Int] toList' value = withStream value S.toList +{-# NOINLINE eqByPure #-} eqByPure :: Int -> IO Bool eqByPure value = withPureStream value $ \src -> runIdentity $ S.eqBy (==) src src @@ -645,6 +674,7 @@ inspect $ 'eqByPure `hasNoType` ''S.Step inspect $ 'eqByPure `hasNoType` ''Fold.Step #endif +{-# NOINLINE cmpByPure #-} cmpByPure :: Int -> IO Ordering cmpByPure value = withPureStream value $ \src -> runIdentity $ S.cmpBy compare src src @@ -656,6 +686,7 @@ inspect $ 'cmpByPure `hasNoType` ''S.Step inspect $ 'cmpByPure `hasNoType` ''Fold.Step #endif +{-# NOINLINE eqBy #-} eqBy :: Int -> IO Bool eqBy value = withStream value $ \src -> S.eqBy (==) src src @@ -666,6 +697,7 @@ inspect $ 'eqBy `hasNoType` ''S.Step inspect $ 'eqBy `hasNoType` ''Fold.Step #endif +{-# NOINLINE cmpBy #-} cmpBy :: Int -> IO Ordering cmpBy value = withStream value $ \src -> S.cmpBy compare src src @@ -688,6 +720,7 @@ mapN n = composeN n $ fmap (+ 1) mapM :: MonadAsync m => Int -> Stream m Int -> m () mapM n = composeN n $ Stream.mapM return +{-# NOINLINE map1 #-} map1 :: Int -> IO () map1 value = withStream value (mapN 1) @@ -698,6 +731,7 @@ inspect $ 'map1 `hasNoType` ''FL.Step inspect $ 'map1 `hasNoType` ''SPEC #endif +{-# NOINLINE mapM1 #-} mapM1 :: Int -> IO () mapM1 value = withStream value (mapM 1) @@ -708,6 +742,7 @@ inspect $ 'mapM1 `hasNoType` ''FL.Step inspect $ 'mapM1 `hasNoType` ''SPEC #endif +{-# NOINLINE mapN4 #-} mapN4 :: Int -> IO () mapN4 value = withStream value (mapN 4) @@ -718,6 +753,7 @@ inspect $ 'mapN4 `hasNoType` ''FL.Step inspect $ 'mapN4 `hasNoType` ''SPEC #endif +{-# NOINLINE mapM4 #-} mapM4 :: Int -> IO () mapM4 value = withStream value (mapM 4) @@ -740,6 +776,7 @@ _takeOne n = composeN n $ Stream.take 1 takeAll :: MonadIO m => Int -> Int -> Stream m Int -> m () takeAll value n = composeN n $ Stream.take (value + 1) +{-# NOINLINE takeAll1 #-} takeAll1 :: Int -> IO () takeAll1 value = withStream value (takeAll value 1) @@ -750,6 +787,7 @@ inspect $ 'takeAll1 `hasNoType` ''FL.Step inspect $ 'takeAll1 `hasNoType` ''SPEC #endif +{-# NOINLINE takeAll4 #-} takeAll4 :: Int -> IO () takeAll4 value = withStream value (takeAll value 4) @@ -764,6 +802,7 @@ inspect $ 'takeAll4 `hasNoType` ''SPEC takeWhileTrue :: MonadIO m => Int -> Int -> Stream m Int -> m () takeWhileTrue value n = composeN n $ Stream.takeWhile (<= (value + 1)) +{-# NOINLINE takeWhileTrue1 #-} takeWhileTrue1 :: Int -> IO () takeWhileTrue1 value = withStream value (takeWhileTrue value 1) @@ -774,6 +813,7 @@ inspect $ 'takeWhileTrue1 `hasNoType` ''FL.Step inspect $ 'takeWhileTrue1 `hasNoType` ''SPEC #endif +{-# NOINLINE takeWhileTrue4 #-} takeWhileTrue4 :: Int -> IO () takeWhileTrue4 value = withStream value (takeWhileTrue value 4) @@ -788,6 +828,7 @@ inspect $ 'takeWhileTrue4 `hasNoType` ''SPEC takeWhileMTrue :: MonadIO m => Int -> Int -> Stream m Int -> m () takeWhileMTrue value n = composeN n $ Stream.takeWhileM (return . (<= (value + 1))) +{-# NOINLINE takeWhileMTrue4 #-} takeWhileMTrue4 :: Int -> IO () takeWhileMTrue4 value = withStream value (takeWhileMTrue value 4) diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Type/Logic.hs b/benchmark/Streamly/Benchmark/Data/Stream/Type/Logic.hs index 5ab5dfaf55..ddeee45a81 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Type/Logic.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Type/Logic.hs @@ -113,22 +113,27 @@ unfoldEachEqn maxVal input ints = $ Stream.mapM (checkPair maxVal) $ Stream.unfoldEach intu ints +{-# NOINLINE concatForBounded #-} concatForBounded :: Int -> IO () concatForBounded maxVal = withRandomIntIO $ \n -> concatForEqn maxVal (boundedInts maxVal n) +{-# NOINLINE streamCrossBounded #-} streamCrossBounded :: Int -> IO () streamCrossBounded maxVal = withRandomIntIO $ \n -> streamCrossEqn maxVal (boundedInts maxVal n) +{-# NOINLINE fairStreamCrossBounded #-} fairStreamCrossBounded :: Int -> IO () fairStreamCrossBounded maxVal = withRandomIntIO $ \n -> fairStreamCrossEqn maxVal (boundedInts maxVal n) +{-# NOINLINE fairStreamCrossInfinite #-} fairStreamCrossInfinite :: Int -> IO () fairStreamCrossInfinite maxVal = withRandomIntIO $ \n -> fairStreamCrossEqn maxVal (infiniteInts maxVal n) +{-# NOINLINE unfoldEachBounded #-} unfoldEachBounded :: Int -> IO () unfoldEachBounded maxVal = withRandomIntIO $ \n -> unfoldEachEqn maxVal (boundedIntsUnfold maxVal 0) (boundedInts maxVal n) diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Type/MultiStream.hs b/benchmark/Streamly/Benchmark/Data/Stream/Type/MultiStream.hs index 3cee23c294..cc408ec55c 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Type/MultiStream.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Type/MultiStream.hs @@ -57,6 +57,7 @@ import Prelude hiding (concatMap, zipWith) -- Appending ------------------------------------------------------------------------------- +{-# NOINLINE serial2 #-} serial2 :: Int -> IO () serial2 count = withRandomIntIO $ \n -> drain $ @@ -72,6 +73,7 @@ inspect $ 'serial2 `hasNoType` ''S.Step inspect $ 'serial2 `hasNoType` ''Fold.Step #endif +{-# NOINLINE serial4 #-} serial4 :: Int -> IO () serial4 count = withRandomIntIO $ \n -> drain $ @@ -95,6 +97,7 @@ inspect $ 'serial4 `hasNoType` ''Fold.Step -- Zipping ------------------------------------------------------------------------------- +{-# NOINLINE zipWith #-} zipWith :: Int -> IO () zipWith value = withRandomIntIO $ \n -> let src = sourceUnfoldrM value n @@ -106,6 +109,7 @@ inspect $ 'zipWith `hasNoType` ''SPEC inspect $ 'zipWith `hasNoType` ''Fold.Step #endif +{-# NOINLINE zipWithM #-} zipWithM :: Int -> IO () zipWithM value = withRandomIntIO $ \n -> let src = sourceUnfoldrM value n @@ -131,6 +135,7 @@ sourceConcatMapStreams :: Monad m => Int -> Int -> Int -> Stream m (Stream m Int sourceConcatMapStreams outer inner start = fmap (sourceUnfoldr inner) $ sourceUnfoldr outer start +{-# NOINLINE concatMap #-} concatMap :: Int -> Int -> IO () concatMap outer inner = withRandomIntIO $ \n -> drain $ S.concatMap @@ -144,6 +149,7 @@ inspect $ 'concatMap `hasNoType` ''SPEC inspect $ 'concatMap `hasNoType` ''Fold.Step #endif +{-# NOINLINE concatMapM2 #-} concatMapM2 :: Int -> IO () concatMapM2 value = withStream value $ \s -> drain $ do @@ -151,6 +157,7 @@ concatMapM2 value = withStream value $ \s -> pure $ Stream.concatMapM (\y -> pure $ Stream.fromPure $ x + y) s) s +{-# NOINLINE concatMapM3 #-} concatMapM3 :: Int -> IO () concatMapM3 value = withStream value $ \s -> drain $ do @@ -159,6 +166,7 @@ concatMapM3 value = withStream value $ \s -> pure $ Stream.concatMapM (\z -> pure $ Stream.fromPure $ x + y + z) s) s) s +{-# NOINLINE concatMapViaUnfoldEach #-} concatMapViaUnfoldEach :: Int -> Int -> IO () concatMapViaUnfoldEach outer inner = withRandomIntIO $ \n -> drain $ cmap @@ -169,6 +177,7 @@ concatMapViaUnfoldEach outer inner = withRandomIntIO $ \n -> cmap f = Stream.unfoldEach (UF.lmap f UF.fromStream) +{-# NOINLINE concatMapM #-} concatMapM :: Int -> Int -> IO () concatMapM outer inner = withRandomIntIO $ \n -> drain $ S.concatMapM @@ -177,16 +186,19 @@ concatMapM outer inner = withRandomIntIO $ \n -> -- concatMap Streams +{-# NOINLINE concatMapSingletonStreams #-} concatMapSingletonStreams :: Int -> IO () concatMapSingletonStreams value = withRandomIntIO (drain . S.concatMap id . sourceConcatMapSingletonStreams value) +{-# NOINLINE concatMapStreams #-} concatMapStreams :: Int -> Int -> IO () concatMapStreams outer inner = withRandomIntIO (S.drain . S.concatMap id . sourceConcatMapStreams outer inner) -- concatMap unfoldr/unfoldr +{-# NOINLINE concatMapPure #-} concatMapPure :: Int -> Int -> IO () concatMapPure outer inner = withRandomIntIO $ \n -> drain $ S.concatMap @@ -216,6 +228,7 @@ sourceUnfoldrMUnfold size start = UF.unfoldrM step then Just (i, i + 1) else Nothing +{-# NOINLINE unfoldEach #-} unfoldEach :: Int -> Int -> IO () unfoldEach outer inner = withRandomIntIO $ \start -> drain $ S.unfoldEach (sourceUnfoldrMUnfold inner start) @@ -229,6 +242,7 @@ inspect $ 'unfoldEach `hasNoType` ''S.Step inspect $ 'unfoldEach `hasNoType` ''Fold.Step #endif +{-# NOINLINE unfoldEach2 #-} unfoldEach2 :: Int -> Int -> IO () unfoldEach2 outer inner = withRandomIntIO $ \start -> drain $ S.unfoldEach (UF.carryInput (sourceUnfoldrMUnfold inner start)) @@ -242,6 +256,7 @@ inspect $ 'unfoldEach2 `hasNoType` ''Fold.Step inspect $ 'unfoldEach2 `hasNoType` ''SPEC #endif +{-# NOINLINE unfoldEach3 #-} unfoldEach3 :: Int -> IO () unfoldEach3 linearCount = withRandomIntIO $ \start -> drain $ do S.unfoldEach (UF.carryInput (UF.lmap snd (sourceUnfoldrMUnfold nestedCount3 start))) @@ -259,6 +274,7 @@ inspect $ 'unfoldEach3 `hasNoType` ''Fold.Step inspect $ 'unfoldEach3 `hasNoType` ''SPEC #endif +{-# NOINLINE unfoldCross #-} unfoldCross :: Int -> Int -> IO () unfoldCross outer inner = withRandomIntIO $ \start -> drain $ Stream.unfoldCross @@ -279,6 +295,7 @@ inspect $ 'unfoldCross `hasNoType` ''SPEC -- Fold Many ------------------------------------------------------------------------------- +{-# NOINLINE foldMany #-} foldMany :: Int -> IO () foldMany value = withStream value $ @@ -295,6 +312,7 @@ inspect $ 'foldMany `hasNoType` ''FL.Step inspect $ 'foldMany `hasNoType` ''SPEC #endif +{-# NOINLINE foldMany1 #-} foldMany1 :: Int -> IO () foldMany1 value = withStream value $ @@ -311,6 +329,7 @@ inspect $ 'foldMany1 `hasNoType` ''FL.Step inspect $ 'foldMany1 `hasNoType` ''SPEC #endif +{-# NOINLINE refoldMany #-} refoldMany :: Int -> IO () refoldMany value = withStream value $ @@ -328,6 +347,7 @@ inspect $ 'refoldMany `hasNoType` ''SPEC #endif -- {-# INLINE refoldIterateM #-} +{-# NOINLINE refoldIterateM #-} refoldIterateM :: Int -> IO () refoldIterateM value = withStream value $ diff --git a/benchmark/Streamly/Benchmark/Data/Stream/Type/Nested.hs b/benchmark/Streamly/Benchmark/Data/Stream/Type/Nested.hs index 3886d92977..f58fee36d2 100644 --- a/benchmark/Streamly/Benchmark/Data/Stream/Type/Nested.hs +++ b/benchmark/Streamly/Benchmark/Data/Stream/Type/Nested.hs @@ -36,7 +36,7 @@ unCross = Stream.unNested ------------------------------------------------------------------------------- {-# INLINE toNullApPure #-} -toNullApPure :: MonadAsync m => Int -> Int -> m () +toNullApPure :: Int -> Int -> IO () toNullApPure linearCount start = drain $ unCross $ (+) <$> mkCross (sourceUnfoldr nestedCount2 start) <*> mkCross (sourceUnfoldr nestedCount2 start) @@ -46,7 +46,7 @@ toNullApPure linearCount start = drain $ unCross $ nestedCount2 = round (fromIntegral linearCount**(1/2::Double)) {-# INLINE toNullMPure #-} -toNullMPure :: MonadAsync m => Int -> Int -> m () +toNullMPure :: Int -> Int -> IO () toNullMPure linearCount start = drain $ unCross $ do x <- mkCross (sourceUnfoldr nestedCount2 start) y <- mkCross (sourceUnfoldr nestedCount2 start) @@ -57,7 +57,7 @@ toNullMPure linearCount start = drain $ unCross $ do nestedCount2 = round (fromIntegral linearCount**(1/2::Double)) {-# INLINE toNullM3Pure #-} -toNullM3Pure :: MonadAsync m => Int -> Int -> m () +toNullM3Pure :: Int -> Int -> IO () toNullM3Pure linearCount start = drain $ unCross $ do x <- mkCross (sourceUnfoldr nestedCount3 start) y <- mkCross (sourceUnfoldr nestedCount3 start) @@ -69,7 +69,7 @@ toNullM3Pure linearCount start = drain $ unCross $ do nestedCount3 = round (fromIntegral linearCount**(1/3::Double)) {-# INLINE filterAllOutMPure #-} -filterAllOutMPure :: MonadAsync m => Int -> Int -> m () +filterAllOutMPure :: Int -> Int -> IO () filterAllOutMPure linearCount start = drain $ unCross $ do x <- mkCross (sourceUnfoldr nestedCount2 start) y <- mkCross (sourceUnfoldr nestedCount2 start) @@ -83,7 +83,7 @@ filterAllOutMPure linearCount start = drain $ unCross $ do nestedCount2 = round (fromIntegral linearCount**(1/2::Double)) {-# INLINE filterAllInMPure #-} -filterAllInMPure :: MonadAsync m => Int -> Int -> m () +filterAllInMPure :: Int -> Int -> IO () filterAllInMPure linearCount start = drain $ unCross $ do x <- mkCross (sourceUnfoldr nestedCount2 start) y <- mkCross (sourceUnfoldr nestedCount2 start) @@ -96,6 +96,7 @@ filterAllInMPure linearCount start = drain $ unCross $ do nestedCount2 = round (fromIntegral linearCount**(1/2::Double)) +{-# NOINLINE cross2 #-} cross2 :: Int -> IO () cross2 linearCount = withRandomIntIO $ \start -> drain $ Stream.crossWith (+) @@ -106,6 +107,7 @@ cross2 linearCount = withRandomIntIO $ \start -> drain $ nestedCount2 = round (fromIntegral linearCount**(1/2::Double)) +{-# NOINLINE crossApply #-} crossApply :: Int -> IO () crossApply linearCount = withRandomIntIO $ \start -> drain $ Stream.crossApply @@ -116,6 +118,7 @@ crossApply linearCount = withRandomIntIO $ \start -> drain $ nestedCount2 = round (fromIntegral linearCount**(1/2::Double)) +{-# NOINLINE crossApplyFst #-} crossApplyFst :: Int -> IO () crossApplyFst linearCount = withRandomIntIO $ \start -> drain $ Stream.crossApplyFst @@ -126,6 +129,7 @@ crossApplyFst linearCount = withRandomIntIO $ \start -> drain $ nestedCount2 = round (fromIntegral linearCount**(1/2::Double)) +{-# NOINLINE crossApplySnd #-} crossApplySnd :: Int -> IO () crossApplySnd linearCount = withRandomIntIO $ \start -> drain $ Stream.crossApplySnd @@ -140,11 +144,13 @@ crossApplySnd linearCount = withRandomIntIO $ \start -> drain $ -- Monad ------------------------------------------------------------------------------- +{-# NOINLINE drainConcatFor1 #-} drainConcatFor1 :: Int -> IO () drainConcatFor1 count = withStream count $ \s -> drain $ Stream.concatFor s $ \x -> Stream.fromPure $ x + 1 +{-# NOINLINE drainConcatFor #-} drainConcatFor :: Int -> IO () drainConcatFor count = withStream count $ \s -> drain $ do @@ -152,6 +158,7 @@ drainConcatFor count = withStream count $ \s -> Stream.concatFor s $ \y -> Stream.fromPure $ x + y +{-# NOINLINE drainConcatForM #-} drainConcatForM :: Int -> IO () drainConcatForM count = withStream count $ \s -> drain $ do @@ -159,6 +166,7 @@ drainConcatForM count = withStream count $ \s -> pure $ Stream.concatForM s $ \y -> pure $ Stream.fromPure $ x + y +{-# NOINLINE drainConcatFor3 #-} drainConcatFor3 :: Int -> IO () drainConcatFor3 count = withStream count $ \s -> drain $ do @@ -167,6 +175,7 @@ drainConcatFor3 count = withStream count $ \s -> Stream.concatFor s $ \z -> Stream.fromPure $ x + y + z +{-# NOINLINE drainConcatFor4 #-} drainConcatFor4 :: Int -> IO () drainConcatFor4 count = withStream count $ \s -> drain $ do @@ -176,6 +185,7 @@ drainConcatFor4 count = withStream count $ \s -> Stream.concatFor s $ \w -> Stream.fromPure $ x + y + z + w +{-# NOINLINE drainConcatFor5 #-} drainConcatFor5 :: Int -> IO () drainConcatFor5 count = withStream count $ \s -> drain $ do @@ -186,6 +196,7 @@ drainConcatFor5 count = withStream count $ \s -> Stream.concatFor s $ \u -> Stream.fromPure $ x + y + z + w + u +{-# NOINLINE drainConcatFor3M #-} drainConcatFor3M :: Int -> IO () drainConcatFor3M count = withStream count $ \s -> drain $ do @@ -194,6 +205,7 @@ drainConcatFor3M count = withStream count $ \s -> pure $ Stream.concatForM s $ \z -> pure $ Stream.fromPure $ x + y + z +{-# NOINLINE filterAllInConcatFor #-} filterAllInConcatFor :: Int -> IO () filterAllInConcatFor count = withStream count $ \s -> drain $ do @@ -204,6 +216,7 @@ filterAllInConcatFor count = withStream count $ \s -> then Stream.fromPure s1 else Stream.nil +{-# NOINLINE filterAllOutConcatFor #-} filterAllOutConcatFor :: Int -> IO () filterAllOutConcatFor count = withStream count $ \s -> drain $ do From bc9c8dc813109b546ce4ae91aaafe4258d01b3dc Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Wed, 1 Jul 2026 05:10:39 +0530 Subject: [PATCH 2/6] Add NOINLINE on scanl benchmarks --- .../Benchmark/Data/Scanl/Combinators.hs | 103 +++++++++--------- .../Benchmark/Data/Scanl/Container.hs | 38 ++++--- .../Streamly/Benchmark/Data/Scanl/Type.hs | 77 ++++++------- .../Streamly/Benchmark/Data/Scanl/Window.hs | 13 +++ 4 files changed, 126 insertions(+), 105 deletions(-) diff --git a/benchmark/Streamly/Benchmark/Data/Scanl/Combinators.hs b/benchmark/Streamly/Benchmark/Data/Scanl/Combinators.hs index f08bb86051..ddb458ff0d 100644 --- a/benchmark/Streamly/Benchmark/Data/Scanl/Combinators.hs +++ b/benchmark/Streamly/Benchmark/Data/Scanl/Combinators.hs @@ -7,6 +7,7 @@ #undef FUSION_CHECK #ifdef FUSION_CHECK +{-# OPTIONS_GHC -fplugin-opt=Fusion.Plugin:verbose=2 #-} {-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-} #endif @@ -84,7 +85,7 @@ oddEven x = if odd x then Left x else Right x -- Semigroups and monoids ------------------------------------------------------------------------------- -{-# INLINE sconcat #-} +{-# NOINLINE sconcat #-} sconcat :: Int -> IO () sconcat n = withPostscanlMap n Sum (Scanl.sconcat (Sum 0)) @@ -94,7 +95,7 @@ inspect $ 'sconcat `hasNoType` ''FL.Step inspect $ 'sconcat `hasNoType` ''SPEC #endif -{-# INLINE mconcat #-} +{-# NOINLINE mconcat #-} mconcat :: Int -> IO () mconcat n = withPostscanlMap n Sum Scanl.mconcat @@ -104,7 +105,7 @@ inspect $ 'mconcat `hasNoType` ''FL.Step inspect $ 'mconcat `hasNoType` ''SPEC #endif -{-# INLINE foldMap #-} +{-# NOINLINE foldMap #-} foldMap :: Int -> IO () foldMap n = withPostscanl n (Scanl.foldMap Sum) @@ -114,7 +115,7 @@ inspect $ 'foldMap `hasNoType` ''FL.Step inspect $ 'foldMap `hasNoType` ''SPEC #endif -{-# INLINE foldMapM #-} +{-# NOINLINE foldMapM #-} foldMapM :: Int -> IO () foldMapM n = withPostscanl n (Scanl.foldMapM (return . Sum)) @@ -128,7 +129,7 @@ inspect $ 'foldMapM `hasNoType` ''SPEC -- Reducers ------------------------------------------------------------------------------- -{-# INLINE drainMapM #-} +{-# NOINLINE drainMapM #-} drainMapM :: Int -> IO () drainMapM n = withPostscanl n (Scanl.drainMapM return) @@ -138,7 +139,7 @@ inspect $ 'drainMapM `hasNoType` ''FL.Step inspect $ 'drainMapM `hasNoType` ''SPEC #endif -{-# INLINE the #-} +{-# NOINLINE the #-} the :: Int -> IO () the n = withPostscanlMap n (const (1 :: Int)) Scanl.the @@ -148,7 +149,7 @@ inspect $ 'the `hasNoType` ''FL.Step inspect $ 'the `hasNoType` ''SPEC #endif -{-# INLINE mean #-} +{-# NOINLINE mean #-} mean :: Int -> IO () mean n = withPostscanlMap n (fromIntegral :: Int -> Double) Scanl.mean @@ -158,7 +159,7 @@ inspect $ 'mean `hasNoType` ''FL.Step inspect $ 'mean `hasNoType` ''SPEC #endif -{-# INLINE rollingHash #-} +{-# NOINLINE rollingHash #-} rollingHash :: Int -> IO () rollingHash n = withPostscanl n Scanl.rollingHash @@ -168,7 +169,7 @@ inspect $ 'rollingHash `hasNoType` ''FL.Step inspect $ 'rollingHash `hasNoType` ''SPEC #endif -{-# INLINE rollingHashWithSalt #-} +{-# NOINLINE rollingHashWithSalt #-} rollingHashWithSalt :: Int -> IO () rollingHashWithSalt n = withPostscanl n (Scanl.rollingHashWithSalt Scanl.defaultSalt) @@ -178,7 +179,7 @@ inspect $ 'rollingHashWithSalt `hasNoType` ''FL.Step inspect $ 'rollingHashWithSalt `hasNoType` ''SPEC #endif -{-# INLINE rollingHashFirstN #-} +{-# NOINLINE rollingHashFirstN #-} rollingHashFirstN :: Int -> IO () rollingHashFirstN n = withPostscanl n (Scanl.rollingHashFirstN n) @@ -187,7 +188,7 @@ inspect $ 'rollingHashFirstN `hasNoType` ''Step inspect $ 'rollingHashFirstN `hasNoType` ''SPEC #endif -{-# INLINE sum #-} +{-# NOINLINE sum #-} sum :: Int -> IO () sum n = withPostscanl n Scanl.sum @@ -197,7 +198,7 @@ inspect $ 'sum `hasNoType` ''FL.Step inspect $ 'sum `hasNoType` ''SPEC #endif -{-# INLINE product #-} +{-# NOINLINE product #-} product :: Int -> IO () product n = withPostscanl n Scanl.product @@ -211,7 +212,7 @@ inspect $ 'product `hasNoType` ''SPEC -- Scanners ------------------------------------------------------------------------------- -{-# INLINE indexingWith #-} +{-# NOINLINE indexingWith #-} indexingWith :: Int -> IO () indexingWith n = withPostscanl n (Scanl.indexingWith 0 (+ 1)) @@ -221,7 +222,7 @@ inspect $ 'indexingWith `hasNoType` ''FL.Step inspect $ 'indexingWith `hasNoType` ''SPEC #endif -{-# INLINE indexing #-} +{-# NOINLINE indexing #-} indexing :: Int -> IO () indexing n = withPostscanl n Scanl.indexing @@ -231,7 +232,7 @@ inspect $ 'indexing `hasNoType` ''FL.Step inspect $ 'indexing `hasNoType` ''SPEC #endif -{-# INLINE indexingRev #-} +{-# NOINLINE indexingRev #-} indexingRev :: Int -> IO () indexingRev n = withPostscanl n (Scanl.indexingRev n) @@ -241,7 +242,7 @@ inspect $ 'indexingRev `hasNoType` ''FL.Step inspect $ 'indexingRev `hasNoType` ''SPEC #endif -{-# INLINE rollingMap #-} +{-# NOINLINE rollingMap #-} rollingMap :: Int -> IO () rollingMap n = withPostscanl n (Scanl.rollingMap (\_ x -> x)) @@ -251,7 +252,7 @@ inspect $ 'rollingMap `hasNoType` ''FL.Step inspect $ 'rollingMap `hasNoType` ''SPEC #endif -{-# INLINE rollingMapM #-} +{-# NOINLINE rollingMapM #-} rollingMapM :: Int -> IO () rollingMapM n = withPostscanl n (Scanl.rollingMapM (\_ x -> return x)) @@ -265,7 +266,7 @@ inspect $ 'rollingMapM `hasNoType` ''SPEC -- Filters ------------------------------------------------------------------------------- -{-# INLINE deleteBy #-} +{-# NOINLINE deleteBy #-} deleteBy :: Int -> IO () deleteBy n = withPostscanl n (Scanl.deleteBy (==) 0) @@ -275,7 +276,7 @@ inspect $ 'deleteBy `hasNoType` ''FL.Step inspect $ 'deleteBy `hasNoType` ''SPEC #endif -{-# INLINE uniqBy #-} +{-# NOINLINE uniqBy #-} uniqBy :: Int -> IO () uniqBy n = withPostscanl n (Scanl.uniqBy (==)) @@ -285,7 +286,7 @@ inspect $ 'uniqBy `hasNoType` ''FL.Step inspect $ 'uniqBy `hasNoType` ''SPEC #endif -{-# INLINE uniq #-} +{-# NOINLINE uniq #-} uniq :: Int -> IO () uniq n = withPostscanl n Scanl.uniq @@ -295,7 +296,7 @@ inspect $ 'uniq `hasNoType` ''FL.Step inspect $ 'uniq `hasNoType` ''SPEC #endif -{-# INLINE findIndices #-} +{-# NOINLINE findIndices #-} findIndices :: Int -> IO () findIndices n = withPostscanl n (Scanl.findIndices (== n)) @@ -305,7 +306,7 @@ inspect $ 'findIndices `hasNoType` ''FL.Step inspect $ 'findIndices `hasNoType` ''SPEC #endif -{-# INLINE elemIndices #-} +{-# NOINLINE elemIndices #-} elemIndices :: Int -> IO () elemIndices n = withPostscanl n (Scanl.elemIndices n) @@ -319,7 +320,7 @@ inspect $ 'elemIndices `hasNoType` ''SPEC -- Multi-element scans ------------------------------------------------------------------------------- -{-# INLINE drainN #-} +{-# NOINLINE drainN #-} drainN :: Int -> IO () drainN n = withPostscanl n (Scanl.drainN n) @@ -333,7 +334,7 @@ inspect $ 'drainN `hasNoType` ''SPEC -- Trimmers ------------------------------------------------------------------------------- -{-# INLINE takingEndByM #-} +{-# NOINLINE takingEndByM #-} takingEndByM :: Int -> IO () takingEndByM n = withPostscanl n (Scanl.takingEndByM (return . (>= n))) @@ -343,7 +344,7 @@ inspect $ 'takingEndByM `hasNoType` ''FL.Step inspect $ 'takingEndByM `hasNoType` ''SPEC #endif -{-# INLINE takingEndBy #-} +{-# NOINLINE takingEndBy #-} takingEndBy :: Int -> IO () takingEndBy n = withPostscanl n (Scanl.takingEndBy (>= n)) @@ -353,7 +354,7 @@ inspect $ 'takingEndBy `hasNoType` ''FL.Step inspect $ 'takingEndBy `hasNoType` ''SPEC #endif -{-# INLINE takingEndByM_ #-} +{-# NOINLINE takingEndByM_ #-} takingEndByM_ :: Int -> IO () takingEndByM_ n = withPostscanl n (Scanl.takingEndByM_ (return . (>= n))) @@ -363,7 +364,7 @@ inspect $ 'takingEndByM_ `hasNoType` ''FL.Step inspect $ 'takingEndByM_ `hasNoType` ''SPEC #endif -{-# INLINE takingEndBy_ #-} +{-# NOINLINE takingEndBy_ #-} takingEndBy_ :: Int -> IO () takingEndBy_ n = withPostscanl n (Scanl.takingEndBy_ (>= n)) @@ -373,7 +374,7 @@ inspect $ 'takingEndBy_ `hasNoType` ''FL.Step inspect $ 'takingEndBy_ `hasNoType` ''SPEC #endif -{-# INLINE droppingWhileM #-} +{-# NOINLINE droppingWhileM #-} droppingWhileM :: Int -> IO () droppingWhileM n = withPostscanl n (Scanl.droppingWhileM (return . (<= n))) @@ -383,7 +384,7 @@ inspect $ 'droppingWhileM `hasNoType` ''FL.Step inspect $ 'droppingWhileM `hasNoType` ''SPEC #endif -{-# INLINE droppingWhile #-} +{-# NOINLINE droppingWhile #-} droppingWhile :: Int -> IO () droppingWhile n = withPostscanl n (Scanl.droppingWhile (<= n)) @@ -397,7 +398,7 @@ inspect $ 'droppingWhile `hasNoType` ''SPEC -- Scanning input ------------------------------------------------------------------------------- -{-# INLINE compose #-} +{-# NOINLINE compose #-} compose :: Int -> IO () compose n = withPostscanl n (Scanl.compose Scanl.sum Scanl.drain) @@ -406,7 +407,7 @@ inspect $ 'compose `hasNoType` ''Step inspect $ 'compose `hasNoType` ''SPEC #endif -{-# INLINE composeMany #-} +{-# NOINLINE composeMany #-} composeMany :: Int -> IO () composeMany n = withPostscanl n (Scanl.composeMany (Scanl.take 2 Scanl.sum) Scanl.drain) @@ -415,7 +416,7 @@ inspect $ 'composeMany `hasNoType` ''Step inspect $ 'composeMany `hasNoType` ''SPEC #endif -{-# INLINE pipe #-} +{-# NOINLINE pipe #-} pipe :: Int -> IO () pipe n = withPostscanl n (Scanl.pipe (Pipe.mapM (\x -> return (x + 1))) Scanl.drain) @@ -425,7 +426,7 @@ inspect $ 'pipe `hasNoType` ''FL.Step inspect $ 'pipe `hasNoType` ''SPEC #endif -{-# INLINE indexed #-} +{-# NOINLINE indexed #-} indexed :: Int -> IO () indexed n = withPostscanl n (Scanl.indexed Scanl.length) @@ -438,7 +439,7 @@ inspect $ 'indexed `hasNoType` ''SPEC -- Filtering input ------------------------------------------------------------------------------- -{-# INLINE mapMaybeM #-} +{-# NOINLINE mapMaybeM #-} mapMaybeM :: Int -> IO () mapMaybeM n = withPostscanl n @@ -452,7 +453,7 @@ inspect $ 'mapMaybeM `hasNoType` ''FL.Step inspect $ 'mapMaybeM `hasNoType` ''SPEC #endif -{-# INLINE mapMaybe #-} +{-# NOINLINE mapMaybe #-} mapMaybe :: Int -> IO () mapMaybe n = withPostscanl n @@ -464,7 +465,7 @@ inspect $ 'mapMaybe `hasNoType` ''FL.Step inspect $ 'mapMaybe `hasNoType` ''SPEC #endif -{-# INLINE sampleFromthen #-} +{-# NOINLINE sampleFromthen #-} sampleFromthen :: Int -> IO () sampleFromthen n = withPostscanl n (Scanl.sampleFromthen 0 2 Scanl.drain) @@ -477,7 +478,7 @@ inspect $ 'sampleFromthen `hasNoType` ''SPEC -- Parallel distribution ------------------------------------------------------------------------------- -{-# INLINE tee #-} +{-# NOINLINE tee #-} tee :: Int -> IO () tee n = withPostscanl n (Scanl.tee Scanl.sum Scanl.length) @@ -487,7 +488,7 @@ inspect $ 'tee `hasNoType` ''FL.Step inspect $ 'tee `hasNoType` ''SPEC #endif -{-# INLINE distribute #-} +{-# NOINLINE distribute #-} distribute :: Int -> IO () distribute n = withPostscanl n (Scanl.distribute [Scanl.sum, Scanl.length]) @@ -495,7 +496,7 @@ distribute n = withPostscanl n (Scanl.distribute [Scanl.sum, Scanl.length]) -- Unzipping ------------------------------------------------------------------------------- -{-# INLINE unzip #-} +{-# NOINLINE unzip #-} unzip :: Int -> IO () unzip n = withPostscanlMap n (\a -> (a, a)) (Scanl.unzip Scanl.sum Scanl.length) @@ -505,7 +506,7 @@ inspect $ 'unzip `hasNoType` ''FL.Step inspect $ 'unzip `hasNoType` ''SPEC #endif -{-# INLINE unzipWith #-} +{-# NOINLINE unzipWith #-} unzipWith :: Int -> IO () unzipWith n = withPostscanl n (Scanl.unzipWith (\a -> (a, a)) Scanl.sum Scanl.length) @@ -515,7 +516,7 @@ inspect $ 'unzipWith `hasNoType` ''FL.Step inspect $ 'unzipWith `hasNoType` ''SPEC #endif -{-# INLINE unzipWithM #-} +{-# NOINLINE unzipWithM #-} unzipWithM :: Int -> IO () unzipWithM n = withPostscanl n (Scanl.unzipWithM (\a -> return (a, a)) Scanl.sum Scanl.length) @@ -530,7 +531,7 @@ inspect $ 'unzipWithM `hasNoType` ''SPEC -- Partitioning ------------------------------------------------------------------------------- -{-# INLINE partitionByM #-} +{-# NOINLINE partitionByM #-} partitionByM :: Int -> IO () partitionByM n = withPostscanl n (Scanl.partitionByM (return . oddEven) Scanl.sum Scanl.length) @@ -541,7 +542,7 @@ inspect $ 'partitionByM `hasNoType` ''FL.Step inspect $ 'partitionByM `hasNoType` ''SPEC #endif -{-# INLINE partitionBy #-} +{-# NOINLINE partitionBy #-} partitionBy :: Int -> IO () partitionBy n = withPostscanl n (Scanl.partitionBy oddEven Scanl.sum Scanl.length) @@ -551,7 +552,7 @@ inspect $ 'partitionBy `hasNoType` ''FL.Step inspect $ 'partitionBy `hasNoType` ''SPEC #endif -{-# INLINE partition #-} +{-# NOINLINE partition #-} partition :: Int -> IO () partition n = withPostscanlMap n oddEven (Scanl.partition Scanl.sum Scanl.length) @@ -565,37 +566,37 @@ inspect $ 'partition `hasNoType` ''SPEC -- O(n) heap: building structures ------------------------------------------------------------------------------- -{-# INLINE toListRev #-} +{-# NOINLINE toListRev #-} toListRev :: Int -> IO () toListRev n = withPostscanl n Scanl.toListRev -{-# INLINE toStream #-} +{-# NOINLINE toStream #-} toStream :: Int -> IO () toStream n = withStream n $ Stream.fold FL.drain . Stream.postscanl (Scanl.toStream :: Scanl IO Int (Stream IO Int)) -{-# INLINE toStreamRev #-} +{-# NOINLINE toStreamRev #-} toStreamRev :: Int -> IO () toStreamRev n = withStream n $ Stream.fold FL.drain . Stream.postscanl (Scanl.toStreamRev :: Scanl IO Int (Stream IO Int)) -{-# INLINE topBy #-} +{-# NOINLINE topBy #-} topBy :: Int -> IO () topBy n = withPostscanl n (Scanl.topBy compare 10) -{-# INLINE top #-} +{-# NOINLINE top #-} top :: Int -> IO () top n = withPostscanl n (Scanl.top 10) -{-# INLINE bottomBy #-} +{-# NOINLINE bottomBy #-} bottomBy :: Int -> IO () bottomBy n = withPostscanl n (Scanl.bottomBy compare 10) -{-# INLINE bottom #-} +{-# NOINLINE bottom #-} bottom :: Int -> IO () bottom n = withPostscanl n (Scanl.bottom 10) diff --git a/benchmark/Streamly/Benchmark/Data/Scanl/Container.hs b/benchmark/Streamly/Benchmark/Data/Scanl/Container.hs index 68c4094795..00326b7eb9 100644 --- a/benchmark/Streamly/Benchmark/Data/Scanl/Container.hs +++ b/benchmark/Streamly/Benchmark/Data/Scanl/Container.hs @@ -5,6 +5,12 @@ -- License : MIT -- Maintainer : streamly@composewell.com +#undef FUSION_CHECK +#ifdef FUSION_CHECK +{-# OPTIONS_GHC -fplugin-opt=Fusion.Plugin:verbose=2 #-} +{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-} +#endif + #ifdef __HADDOCK_VERSION__ #undef INSPECTION #endif @@ -91,27 +97,27 @@ getScanl k = do -- Set operations ------------------------------------------------------------------------------- -{-# INLINE toSet #-} +{-# NOINLINE toSet #-} toSet :: Int -> IO () toSet n = withPostscanl n Scanl.toSet -{-# INLINE toIntSet #-} +{-# NOINLINE toIntSet #-} toIntSet :: Int -> IO () toIntSet n = withPostscanl n Scanl.toIntSet -{-# INLINE countDistinct #-} +{-# NOINLINE countDistinct #-} countDistinct :: Int -> IO () countDistinct n = withPostscanl n Scanl.countDistinct -{-# INLINE countDistinctInt #-} +{-# NOINLINE countDistinctInt #-} countDistinctInt :: Int -> IO () countDistinctInt n = withPostscanl n Scanl.countDistinctInt -{-# INLINE nub #-} +{-# NOINLINE nub #-} nub :: Int -> IO () nub n = withPostscanl n Scanl.nub -{-# INLINE nubInt #-} +{-# NOINLINE nubInt #-} nubInt :: Int -> IO () nubInt n = withPostscanl n Scanl.nubInt @@ -119,14 +125,14 @@ nubInt n = withPostscanl n Scanl.nubInt -- Demultiplexing ------------------------------------------------------------------------------- -{-# INLINE demuxIOOneShot #-} +{-# NOINLINE demuxIOOneShot #-} demuxIOOneShot :: Int -> IO () demuxIOOneShot len = withStream len $ Stream.fold FL.drain . Stream.postscanl (Scanl.demuxIO (getKey 64) getScanl) -{-# INLINE demuxIOSum #-} +{-# NOINLINE demuxIOSum #-} demuxIOSum :: Int -> IO () demuxIOSum len = withStream len $ @@ -138,7 +144,7 @@ demuxIOSum len = inspect $ 'demuxIOSum `hasNoType` ''SPEC #endif -{-# INLINE demuxSum #-} +{-# NOINLINE demuxSum #-} demuxSum :: Int -> IO () demuxSum len = withStream len $ @@ -146,7 +152,7 @@ demuxSum len = . Stream.postscanl (Scanl.demux (getKey 64) (const (pure (Just Scanl.sum)))) -{-# INLINE demuxGenericSum #-} +{-# NOINLINE demuxGenericSum #-} demuxGenericSum :: Int -> IO () demuxGenericSum len = withStream len $ @@ -155,7 +161,7 @@ demuxGenericSum len = (Scanl.demuxGeneric (getKey 64) (const (pure (Just Scanl.sum))) :: Scanl IO Int (IO (Map Int Int), Maybe (Int, Int))) -{-# INLINE demuxGenericIOSum #-} +{-# NOINLINE demuxGenericIOSum #-} demuxGenericIOSum :: Int -> IO () demuxGenericIOSum len = withStream len $ @@ -168,7 +174,7 @@ demuxGenericIOSum len = -- Classifying ------------------------------------------------------------------------------- -{-# INLINE classifyLimitedSum #-} +{-# NOINLINE classifyLimitedSum #-} classifyLimitedSum :: Int -> IO () classifyLimitedSum len = withStream len $ @@ -180,7 +186,7 @@ inspect $ 'classifyLimitedSum `hasNoType` ''FL.Step inspect $ 'classifyLimitedSum `hasNoType` ''SPEC #endif -{-# INLINE classifyIOSum #-} +{-# NOINLINE classifyIOSum #-} classifyIOSum :: Int -> IO () classifyIOSum len = withStream len $ @@ -192,14 +198,14 @@ inspect $ 'classifyIOSum `hasNoType` ''FL.Step inspect $ 'classifyIOSum `hasNoType` ''SPEC #endif -{-# INLINE classifySum #-} +{-# NOINLINE classifySum #-} classifySum :: Int -> IO () classifySum len = withStream len $ Stream.fold FL.drain . Stream.postscanl (Scanl.classify (getKey 64) Scanl.sum) -{-# INLINE classifyGenericSum #-} +{-# NOINLINE classifyGenericSum #-} classifyGenericSum :: Int -> IO () classifyGenericSum len = withStream len $ @@ -208,7 +214,7 @@ classifyGenericSum len = (Scanl.classifyGeneric (getKey 64) Scanl.sum :: Scanl IO Int (IO (Map Int Int), Maybe (Int, Int))) -{-# INLINE classifyGenericIOSum #-} +{-# NOINLINE classifyGenericIOSum #-} classifyGenericIOSum :: Int -> IO () classifyGenericIOSum len = withStream len $ diff --git a/benchmark/Streamly/Benchmark/Data/Scanl/Type.hs b/benchmark/Streamly/Benchmark/Data/Scanl/Type.hs index 6dc9f1f830..20876a8311 100644 --- a/benchmark/Streamly/Benchmark/Data/Scanl/Type.hs +++ b/benchmark/Streamly/Benchmark/Data/Scanl/Type.hs @@ -7,6 +7,7 @@ #undef FUSION_CHECK #ifdef FUSION_CHECK +{-# OPTIONS_GHC -fplugin-opt=Fusion.Plugin:verbose=2 #-} {-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-} #endif @@ -83,7 +84,7 @@ oddEven x = if odd x then Left x else Right x -- Constructors ------------------------------------------------------------------------------- -{-# INLINE scanl' #-} +{-# NOINLINE scanl' #-} scanl' :: Int -> IO () scanl' n = withPostscanl n (Scanl.scanl' (+) 0) @@ -93,7 +94,7 @@ inspect $ 'scanl' `hasNoType` ''FL.Step inspect $ 'scanl' `hasNoType` ''SPEC #endif -{-# INLINE scanlM' #-} +{-# NOINLINE scanlM' #-} scanlM' :: Int -> IO () scanlM' n = withPostscanl n (Scanl.scanlM' (\b a -> return (b + a)) (return 0)) @@ -103,7 +104,7 @@ inspect $ 'scanlM' `hasNoType` ''FL.Step inspect $ 'scanlM' `hasNoType` ''SPEC #endif -{-# INLINE scanl1' #-} +{-# NOINLINE scanl1' #-} scanl1' :: Int -> IO () scanl1' n = withPostscanl n (Scanl.scanl1' (+)) @@ -113,7 +114,7 @@ inspect $ 'scanl1' `hasNoType` ''FL.Step inspect $ 'scanl1' `hasNoType` ''SPEC #endif -{-# INLINE scanl1M' #-} +{-# NOINLINE scanl1M' #-} scanl1M' :: Int -> IO () scanl1M' n = withPostscanl n (Scanl.scanl1M' (\a b -> return (a + b))) @@ -123,7 +124,7 @@ inspect $ 'scanl1M' `hasNoType` ''FL.Step inspect $ 'scanl1M' `hasNoType` ''SPEC #endif -{-# INLINE scant' #-} +{-# NOINLINE scant' #-} scant' :: Int -> IO () scant' n = withPostscanl n (Scanl.scant' (\s a -> Scanl.Partial (s + a)) (FL.Partial 0) id) @@ -132,7 +133,7 @@ inspect $ 'scant' `hasNoType` ''Step inspect $ 'scant' `hasNoType` ''SPEC #endif -{-# INLINE scantM' #-} +{-# NOINLINE scantM' #-} scantM' :: Int -> IO () scantM' n = withPostscanl n @@ -160,7 +161,7 @@ mkScanrM n = withPostscanl n (Scanl.mkScanrM (\a b -> return (a + b)) (return 0) -- Reducers ------------------------------------------------------------------------------- -{-# INLINE drain #-} +{-# NOINLINE drain #-} drain :: Int -> IO () drain n = withPostscanl n Scanl.drain @@ -170,7 +171,7 @@ inspect $ 'drain `hasNoType` ''FL.Step inspect $ 'drain `hasNoType` ''SPEC #endif -{-# INLINE latest #-} +{-# NOINLINE latest #-} latest :: Int -> IO () latest n = withPostscanl n Scanl.latest @@ -180,7 +181,7 @@ inspect $ 'latest `hasNoType` ''FL.Step inspect $ 'latest `hasNoType` ''SPEC #endif -{-# INLINE functionM #-} +{-# NOINLINE functionM #-} functionM :: Int -> IO () functionM n = withPostscanl n (Scanl.functionM (return . Just)) @@ -190,7 +191,7 @@ inspect $ 'functionM `hasNoType` ''FL.Step inspect $ 'functionM `hasNoType` ''SPEC #endif -{-# INLINE genericLength #-} +{-# NOINLINE genericLength #-} genericLength :: Int -> IO () genericLength n = withPostscanl n (Scanl.genericLength :: Scanl IO Int Int) @@ -200,7 +201,7 @@ inspect $ 'genericLength `hasNoType` ''FL.Step inspect $ 'genericLength `hasNoType` ''SPEC #endif -{-# INLINE length #-} +{-# NOINLINE length #-} length :: Int -> IO () length n = withPostscanl n Scanl.length @@ -210,7 +211,7 @@ inspect $ 'length `hasNoType` ''FL.Step inspect $ 'length `hasNoType` ''SPEC #endif -{-# INLINE maximumBy #-} +{-# NOINLINE maximumBy #-} maximumBy :: Int -> IO () maximumBy n = withPostscanl n (Scanl.maximumBy compare) @@ -220,7 +221,7 @@ inspect $ 'maximumBy `hasNoType` ''FL.Step inspect $ 'maximumBy `hasNoType` ''SPEC #endif -{-# INLINE maximum #-} +{-# NOINLINE maximum #-} maximum :: Int -> IO () maximum n = withPostscanl n Scanl.maximum @@ -230,7 +231,7 @@ inspect $ 'maximum `hasNoType` ''FL.Step inspect $ 'maximum `hasNoType` ''SPEC #endif -{-# INLINE minimumBy #-} +{-# NOINLINE minimumBy #-} minimumBy :: Int -> IO () minimumBy n = withPostscanl n (Scanl.minimumBy compare) @@ -240,7 +241,7 @@ inspect $ 'minimumBy `hasNoType` ''FL.Step inspect $ 'minimumBy `hasNoType` ''SPEC #endif -{-# INLINE minimum #-} +{-# NOINLINE minimum #-} minimum :: Int -> IO () minimum n = withPostscanl n Scanl.minimum @@ -250,7 +251,7 @@ inspect $ 'minimum `hasNoType` ''FL.Step inspect $ 'minimum `hasNoType` ''SPEC #endif -{-# INLINE rangeBy #-} +{-# NOINLINE rangeBy #-} rangeBy :: Int -> IO () rangeBy n = withPostscanl n (Scanl.rangeBy compare) @@ -260,7 +261,7 @@ inspect $ 'rangeBy `hasNoType` ''FL.Step inspect $ 'rangeBy `hasNoType` ''SPEC #endif -{-# INLINE range #-} +{-# NOINLINE range #-} range :: Int -> IO () range n = withPostscanl n Scanl.range @@ -274,7 +275,7 @@ inspect $ 'range `hasNoType` ''SPEC -- Mapping ------------------------------------------------------------------------------- -{-# INLINE rmapM #-} +{-# NOINLINE rmapM #-} rmapM :: Int -> IO () rmapM n = withPostscanl n (Scanl.rmapM return Scanl.drain) @@ -284,7 +285,7 @@ inspect $ 'rmapM `hasNoType` ''FL.Step inspect $ 'rmapM `hasNoType` ''SPEC #endif -{-# INLINE lmap #-} +{-# NOINLINE lmap #-} lmap :: Int -> IO () lmap n = withPostscanl n (Scanl.lmap (+ 1) Scanl.drain) @@ -294,7 +295,7 @@ inspect $ 'lmap `hasNoType` ''FL.Step inspect $ 'lmap `hasNoType` ''SPEC #endif -{-# INLINE lmapM #-} +{-# NOINLINE lmapM #-} lmapM :: Int -> IO () lmapM n = withPostscanl n (Scanl.lmapM return Scanl.drain) @@ -304,7 +305,7 @@ inspect $ 'lmapM `hasNoType` ''FL.Step inspect $ 'lmapM `hasNoType` ''SPEC #endif -{-# INLINE postscanl #-} +{-# NOINLINE postscanl #-} postscanl :: Int -> IO () postscanl n = withPostscanl n (Scanl.postscanl Scanl.length Scanl.drain) @@ -317,7 +318,7 @@ inspect $ 'postscanl `hasNoType` ''SPEC -- Filtering ------------------------------------------------------------------------------- -{-# INLINE catMaybes #-} +{-# NOINLINE catMaybes #-} catMaybes :: Int -> IO () catMaybes n = withPostscanlMap n Just (Scanl.catMaybes Scanl.length) @@ -327,7 +328,7 @@ inspect $ 'catMaybes `hasNoType` ''FL.Step inspect $ 'catMaybes `hasNoType` ''SPEC #endif -{-# INLINE postscanlMaybe #-} +{-# NOINLINE postscanlMaybe #-} postscanlMaybe :: Int -> IO () postscanlMaybe n = withPostscanl n (Scanl.postscanlMaybe (Scanl.filtering even) Scanl.drain) @@ -336,7 +337,7 @@ inspect $ 'postscanlMaybe `hasNoType` ''Step inspect $ 'postscanlMaybe `hasNoType` ''SPEC #endif -{-# INLINE filter #-} +{-# NOINLINE filter #-} filter :: Int -> IO () filter n = withPostscanl n (Scanl.filter even Scanl.drain) @@ -346,7 +347,7 @@ inspect $ 'filter `hasNoType` ''FL.Step inspect $ 'filter `hasNoType` ''SPEC #endif -{-# INLINE filtering #-} +{-# NOINLINE filtering #-} filtering :: Int -> IO () filtering n = withPostscanl n (Scanl.filtering even) @@ -356,7 +357,7 @@ inspect $ 'filtering `hasNoType` ''FL.Step inspect $ 'filtering `hasNoType` ''SPEC #endif -{-# INLINE filterM #-} +{-# NOINLINE filterM #-} filterM :: Int -> IO () filterM n = withPostscanl n (Scanl.filterM (return . even) Scanl.drain) @@ -366,7 +367,7 @@ inspect $ 'filterM `hasNoType` ''FL.Step inspect $ 'filterM `hasNoType` ''SPEC #endif -{-# INLINE catLefts #-} +{-# NOINLINE catLefts #-} catLefts :: Int -> IO () catLefts n = withPostscanlMap n (Left :: Int -> Either Int Int) (Scanl.catLefts Scanl.length) @@ -375,7 +376,7 @@ inspect $ 'catLefts `hasNoType` ''Step inspect $ 'catLefts `hasNoType` ''SPEC #endif -{-# INLINE catRights #-} +{-# NOINLINE catRights #-} catRights :: Int -> IO () catRights n = withPostscanlMap n (Right :: Int -> Either Int Int) (Scanl.catRights Scanl.length) @@ -384,7 +385,7 @@ inspect $ 'catRights `hasNoType` ''Step inspect $ 'catRights `hasNoType` ''SPEC #endif -{-# INLINE catEithers #-} +{-# NOINLINE catEithers #-} catEithers :: Int -> IO () catEithers n = withPostscanlMap n oddEven (Scanl.catEithers Scanl.length) @@ -397,7 +398,7 @@ inspect $ 'catEithers `hasNoType` ''SPEC -- Trimming ------------------------------------------------------------------------------- -{-# INLINE take #-} +{-# NOINLINE take #-} take :: Int -> IO () take n = withPostscanl n (Scanl.take n Scanl.drain) @@ -407,7 +408,7 @@ inspect $ 'take `hasNoType` ''FL.Step inspect $ 'take `hasNoType` ''SPEC #endif -{-# INLINE taking #-} +{-# NOINLINE taking #-} taking :: Int -> IO () taking n = withPostscanl n (Scanl.taking n) @@ -417,7 +418,7 @@ inspect $ 'taking `hasNoType` ''FL.Step inspect $ 'taking `hasNoType` ''SPEC #endif -{-# INLINE takeEndBy_ #-} +{-# NOINLINE takeEndBy_ #-} takeEndBy_ :: Int -> IO () takeEndBy_ n = withPostscanl n (Scanl.takeEndBy_ (>= n) Scanl.drain) @@ -427,7 +428,7 @@ inspect $ 'takeEndBy_ `hasNoType` ''FL.Step inspect $ 'takeEndBy_ `hasNoType` ''SPEC #endif -{-# INLINE takeEndBy #-} +{-# NOINLINE takeEndBy #-} takeEndBy :: Int -> IO () takeEndBy n = withPostscanl n (Scanl.takeEndBy (>= n) Scanl.drain) @@ -437,7 +438,7 @@ inspect $ 'takeEndBy `hasNoType` ''FL.Step inspect $ 'takeEndBy `hasNoType` ''SPEC #endif -{-# INLINE dropping #-} +{-# NOINLINE dropping #-} dropping :: Int -> IO () dropping n = withPostscanl n (Scanl.dropping n) @@ -451,7 +452,7 @@ inspect $ 'dropping `hasNoType` ''SPEC -- Distributing ------------------------------------------------------------------------------- -{-# INLINE teeWith #-} +{-# NOINLINE teeWith #-} teeWith :: Int -> IO () teeWith n = withPostscanl n (Scanl.teeWith (,) Scanl.length Scanl.latest) @@ -465,15 +466,15 @@ inspect $ 'teeWith `hasNoType` ''SPEC -- O(n) heap: building structures ------------------------------------------------------------------------------- -{-# INLINE toList #-} +{-# NOINLINE toList #-} toList :: Int -> IO () toList n = withPostscanl n Scanl.toList -{-# INLINE toStreamK #-} +{-# NOINLINE toStreamK #-} toStreamK :: Int -> IO () toStreamK n = withPostscanl n Scanl.toStreamK -{-# INLINE toStreamKRev #-} +{-# NOINLINE toStreamKRev #-} toStreamKRev :: Int -> IO () toStreamKRev n = withPostscanl n Scanl.toStreamKRev diff --git a/benchmark/Streamly/Benchmark/Data/Scanl/Window.hs b/benchmark/Streamly/Benchmark/Data/Scanl/Window.hs index ea6c452fa2..cd03c3d080 100644 --- a/benchmark/Streamly/Benchmark/Data/Scanl/Window.hs +++ b/benchmark/Streamly/Benchmark/Data/Scanl/Window.hs @@ -1,3 +1,16 @@ +-- | +-- Module : Scanl.Type +-- Copyright : (c) 2024 Composewell +-- +-- License : MIT +-- Maintainer : streamly@composewell.com + +#undef FUSION_CHECK +#ifdef FUSION_CHECK +{-# OPTIONS_GHC -fplugin-opt=Fusion.Plugin:verbose=2 #-} +{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-} +#endif + module Scanl.Window (benchmarks) where import Streamly.Internal.Data.Scanl (Scanl) From de5ed84846dfc0c0cabfe2b008f5f3028f3d873f Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Wed, 1 Jul 2026 07:37:03 +0530 Subject: [PATCH 3/6] Change Scanl.Window benchmarks to use isolated IO actions --- .../Streamly/Benchmark/Data/Scanl/Window.hs | 203 ++++++++++-------- 1 file changed, 119 insertions(+), 84 deletions(-) diff --git a/benchmark/Streamly/Benchmark/Data/Scanl/Window.hs b/benchmark/Streamly/Benchmark/Data/Scanl/Window.hs index cd03c3d080..feac49c02b 100644 --- a/benchmark/Streamly/Benchmark/Data/Scanl/Window.hs +++ b/benchmark/Streamly/Benchmark/Data/Scanl/Window.hs @@ -5,12 +5,6 @@ -- License : MIT -- Maintainer : streamly@composewell.com -#undef FUSION_CHECK -#ifdef FUSION_CHECK -{-# OPTIONS_GHC -fplugin-opt=Fusion.Plugin:verbose=2 #-} -{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-} -#endif - module Scanl.Window (benchmarks) where import Streamly.Internal.Data.Scanl (Scanl) @@ -39,87 +33,128 @@ sourceDescending len from = (from + fromIntegral (len - 1)) from -{-# INLINE sourceDescendingInt #-} -sourceDescendingInt :: Monad m => Int -> Int -> Stream m Int -sourceDescendingInt = sourceDescending - -{-# INLINE benchScanWith #-} -benchScanWith :: Num a => - (Int -> a -> Stream IO a) -> Int -> String -> Scanl IO a b -> Benchmark -benchScanWith src len name f = - bench name - $ nfIO - $ randomRIO (1, 1 :: Int) - >>= Stream.fold Fold.drain - . Stream.postscanl f - . src len - . fromIntegral - -{-# INLINE benchWithPostscan #-} -benchWithPostscan :: Int -> String -> Scanl IO Double a -> Benchmark -benchWithPostscan = benchScanWith source - -{-# INLINE benchWithPostscanInt #-} -benchWithPostscanInt :: Int -> String -> Scanl IO Int a -> Benchmark -benchWithPostscanInt = benchScanWith source +{-# INLINE benchIO #-} +benchIO :: String -> IO () -> Benchmark +benchIO name f = bench name $ nfIO f + +{-# INLINE withStream #-} +withStream :: (Num a, Stream.Enumerable a) => Int -> (Stream IO a -> IO b) -> IO b +withStream n f = randomRIO (1, 1 :: Int) >>= f . source n . fromIntegral + +{-# INLINE withDescStream #-} +withDescStream :: (Num a, Stream.Enumerable a) => Int -> (Stream IO a -> IO b) -> IO b +withDescStream n f = randomRIO (1, 1 :: Int) >>= f . sourceDescending n . fromIntegral + +-- | Run a scan over the stream as a postscan and drain the result. +{-# INLINE withPostscanl #-} +withPostscanl :: Int -> Scanl IO Double b -> IO () +withPostscanl n s = withStream n $ Stream.fold Fold.drain . Stream.postscanl s + +{-# INLINE withPostscanlInt #-} +withPostscanlInt :: Int -> Scanl IO Int b -> IO () +withPostscanlInt n s = withStream n $ Stream.fold Fold.drain . Stream.postscanl s + +{-# INLINE withPostscanlDescInt #-} +withPostscanlDescInt :: Int -> Scanl IO Int b -> IO () +withPostscanlDescInt n s = withDescStream n $ Stream.fold Fold.drain . Stream.postscanl s + +------------------------------------------------------------------------------- +-- benchmarks +------------------------------------------------------------------------------- + +{-# NOINLINE windowMinimum #-} +windowMinimum :: Int -> Int -> IO () +windowMinimum win n = withPostscanl n (Scanl.windowMinimum win) + +{-# NOINLINE windowMinimumInt #-} +windowMinimumInt :: Int -> Int -> IO () +windowMinimumInt win n = withPostscanlInt n (Scanl.windowMinimum win) + +{-# NOINLINE windowMinimumDesc #-} +windowMinimumDesc :: Int -> Int -> IO () +windowMinimumDesc win n = withPostscanlDescInt n (Scanl.windowMinimum win) + +{-# NOINLINE windowMaximum #-} +windowMaximum :: Int -> Int -> IO () +windowMaximum win n = withPostscanl n (Scanl.windowMaximum win) + +{-# NOINLINE windowMaximumDesc #-} +windowMaximumDesc :: Int -> Int -> IO () +windowMaximumDesc win n = withPostscanlDescInt n (Scanl.windowMaximum win) + +{-# NOINLINE windowRange #-} +windowRange :: Int -> Int -> IO () +windowRange win n = withPostscanl n (Scanl.windowRange win) + +{-# NOINLINE windowRangeDesc #-} +windowRangeDesc :: Int -> Int -> IO () +windowRangeDesc win n = withPostscanlDescInt n (Scanl.windowRange win) + +{-# NOINLINE incrSum #-} +incrSum :: Int -> Int -> IO () +incrSum win n = withPostscanl n (Scanl.incrScan win Scanl.incrSum) + +{-# NOINLINE incrSumCumulative #-} +incrSumCumulative :: Int -> IO () +incrSumCumulative n = withPostscanl n (Scanl.cumulativeScan Scanl.incrSum) + +{-# NOINLINE incrSumInt #-} +incrSumInt :: Int -> Int -> IO () +incrSumInt win n = withPostscanlInt n (Scanl.incrScan win Scanl.incrSumInt) + +{-# NOINLINE incrMean #-} +incrMean :: Int -> Int -> IO () +incrMean win n = withPostscanl n (Scanl.incrScan win Scanl.incrMean) + +{-# NOINLINE incrMeanCumulative #-} +incrMeanCumulative :: Int -> IO () +incrMeanCumulative n = withPostscanl n (Scanl.cumulativeScan Scanl.incrMean) + +{-# NOINLINE incrPowerSum #-} +incrPowerSum :: Int -> Int -> IO () +incrPowerSum win n = withPostscanl n (Scanl.incrScan win (Scanl.incrPowerSum 2)) + +{-# NOINLINE incrPowerSumCumulative #-} +incrPowerSumCumulative :: Int -> IO () +incrPowerSumCumulative n = + withPostscanl n (Scanl.cumulativeScan (Scanl.incrPowerSum 2)) benchmarks :: Int -> [(SpaceComplexity, Benchmark)] benchmarks numElements = - [ (SpaceO_1, benchWithPostscan numElements "windowMinimum 10" - (Scanl.windowMinimum 10)) + map (SpaceO_1,) + [ benchIO "windowMinimum 10" (windowMinimum 10 numElements) + , benchIO "windowMinimumInt 10" (windowMinimumInt 10 numElements) -- Below window size 30 the linear search based impl performs better -- than the dequeue based implementation. - , (SpaceO_1, benchWithPostscan numElements "windowMinimum 30" - (Scanl.windowMinimum 30)) - , (SpaceO_1, benchWithPostscan numElements "windowMinimum 1000" - (Scanl.windowMinimum 1000)) - , (SpaceO_1, benchScanWith sourceDescendingInt numElements - "windowMinimum 1000 descending" - (Scanl.windowMinimum 1000)) - - , (SpaceO_1, benchWithPostscan numElements "windowMaximum 10" - (Scanl.windowMaximum 10)) - , (SpaceO_1, benchWithPostscan numElements "windowMaximum 30" - (Scanl.windowMaximum 30)) - , (SpaceO_1, benchWithPostscan numElements "windowMaximum 1000" - (Scanl.windowMaximum 1000)) - , (SpaceO_1, benchScanWith sourceDescendingInt numElements - "windowMaximum 1000 descending" - (Scanl.windowMaximum 1000)) - - , (SpaceO_1, benchWithPostscan numElements "windowRange 10" - (Scanl.windowRange 10)) - , (SpaceO_1, benchWithPostscan numElements "windowRange 30" - (Scanl.windowRange 30)) - , (SpaceO_1, benchWithPostscan numElements "windowRange 1000" - (Scanl.windowRange 1000)) - , (SpaceO_1, benchScanWith sourceDescendingInt numElements - "windowRange 1000 descending" - (Scanl.windowRange 1000)) - - , (SpaceO_1, benchWithPostscan numElements "incrSum 100" - (Scanl.incrScan 100 Scanl.incrSum)) - , (SpaceO_1, benchWithPostscan numElements "incrSum 1000" - (Scanl.incrScan 1000 Scanl.incrSum)) - , (SpaceO_1, benchWithPostscan numElements "incrSum cumulative" - (Scanl.cumulativeScan Scanl.incrSum)) - - , (SpaceO_1, benchWithPostscanInt numElements "incrSumInt 100" - (Scanl.incrScan 100 Scanl.incrSumInt)) - , (SpaceO_1, benchWithPostscanInt numElements "incrSumInt 1000" - (Scanl.incrScan 1000 Scanl.incrSumInt)) - - , (SpaceO_1, benchWithPostscan numElements "incrMean 100" - (Scanl.incrScan 100 Scanl.incrMean)) - , (SpaceO_1, benchWithPostscan numElements "incrMean 1000" - (Scanl.incrScan 1000 Scanl.incrMean)) - , (SpaceO_1, benchWithPostscan numElements "incrMean cumulative" - (Scanl.cumulativeScan Scanl.incrMean)) - - , (SpaceO_1, benchWithPostscan numElements "incrPowerSum 2 100" - (Scanl.incrScan 100 (Scanl.incrPowerSum 2))) - , (SpaceO_1, benchWithPostscan numElements "incrPowerSum 2 1000" - (Scanl.incrScan 1000 (Scanl.incrPowerSum 2))) - , (SpaceO_1, benchWithPostscan numElements "incrPowerSum 2" - (Scanl.cumulativeScan (Scanl.incrPowerSum 2))) + , benchIO "windowMinimum 30" (windowMinimum 30 numElements) + , benchIO "windowMinimum 1000" (windowMinimum 1000 numElements) + , benchIO "windowMinimum 1000 descending" + (windowMinimumDesc 1000 numElements) + + , benchIO "windowMaximum 10" (windowMaximum 10 numElements) + , benchIO "windowMaximum 30" (windowMaximum 30 numElements) + , benchIO "windowMaximum 1000" (windowMaximum 1000 numElements) + , benchIO "windowMaximum 1000 descending" + (windowMaximumDesc 1000 numElements) + + , benchIO "windowRange 10" (windowRange 10 numElements) + , benchIO "windowRange 30" (windowRange 30 numElements) + , benchIO "windowRange 1000" (windowRange 1000 numElements) + , benchIO "windowRange 1000 descending" + (windowRangeDesc 1000 numElements) + + , benchIO "incrSum 100" (incrSum 100 numElements) + , benchIO "incrSum 1000" (incrSum 1000 numElements) + , benchIO "incrSum cumulative" (incrSumCumulative numElements) + + , benchIO "incrSumInt 100" (incrSumInt 100 numElements) + , benchIO "incrSumInt 1000" (incrSumInt 1000 numElements) + + , benchIO "incrMean 100" (incrMean 100 numElements) + , benchIO "incrMean 1000" (incrMean 1000 numElements) + , benchIO "incrMean cumulative" (incrMeanCumulative numElements) + + , benchIO "incrPowerSum 2 100" (incrPowerSum 100 numElements) + , benchIO "incrPowerSum 2 1000" (incrPowerSum 1000 numElements) + , benchIO "incrPowerSum 2" (incrPowerSumCumulative numElements) ] From 8dd9320c589fd780cffbdafd42a61c9d217c55dc Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Fri, 3 Jul 2026 11:38:42 +0530 Subject: [PATCH 4/6] Use latest fusion-plugin * Add -ddump-simpl ghc option in fusion-plugin build * Add fusion-plugin-types dep on benchmarks --- benchmark/streamly-benchmarks.cabal | 3 ++- cabal.project | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/benchmark/streamly-benchmarks.cabal b/benchmark/streamly-benchmarks.cabal index 6ace3f4767..919228cd8a 100644 --- a/benchmark/streamly-benchmarks.cabal +++ b/benchmark/streamly-benchmarks.cabal @@ -155,7 +155,7 @@ common optimization-options ghc-options: -fno-ignore-asserts if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6) - ghc-options: -fplugin Fusion.Plugin + ghc-options: -fplugin Fusion.Plugin -ddump-simpl -ddump-to-file -dsuppress-all else ghc-options: -O0 @@ -194,6 +194,7 @@ common bench-depends if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6) build-depends: fusion-plugin >= 0.2 && < 0.3 + , fusion-plugin-types >= 0.1 && < 0.2 if flag(inspection) build-depends: template-haskell >= 2.14 && < 2.25 diff --git a/cabal.project b/cabal.project index 385bc915db..c7e04e03ea 100644 --- a/cabal.project +++ b/cabal.project @@ -13,4 +13,9 @@ packages: streamly.cabal source-repository-package type: git location: https://github.com/composewell/fusion-plugin.git - tag: 15c0ad50a235a35e85d03cced9ad0f3938565e5a + tag: ce7d4a70e4b78513840d9e603ec907b67f258741 + +source-repository-package + type: git + location: https://github.com/composewell/fusion-plugin-types.git + tag: d4fa57623450ba4a43f08ebd7cfbfc2745035375 From 50a12dae5325d6adcf5be3e4015a1044905ab249 Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Thu, 9 Jul 2026 13:38:27 +0530 Subject: [PATCH 5/6] Add fusion-plugin inspection annotations in Scanl/Container --- .../Benchmark/Data/Scanl/Container.hs | 94 ++++++++++++------- benchmark/streamly-benchmarks.cabal | 7 +- 2 files changed, 65 insertions(+), 36 deletions(-) diff --git a/benchmark/Streamly/Benchmark/Data/Scanl/Container.hs b/benchmark/Streamly/Benchmark/Data/Scanl/Container.hs index 00326b7eb9..c515e524d8 100644 --- a/benchmark/Streamly/Benchmark/Data/Scanl/Container.hs +++ b/benchmark/Streamly/Benchmark/Data/Scanl/Container.hs @@ -5,33 +5,24 @@ -- License : MIT -- Maintainer : streamly@composewell.com -#undef FUSION_CHECK -#ifdef FUSION_CHECK -{-# OPTIONS_GHC -fplugin-opt=Fusion.Plugin:verbose=2 #-} -{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-} -#endif - -#ifdef __HADDOCK_VERSION__ -#undef INSPECTION -#endif - -#ifdef INSPECTION -{-# LANGUAGE TemplateHaskell #-} -{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-} -#endif - {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TemplateHaskellQuotes #-} + {-# OPTIONS_GHC -Wno-orphans #-} -- Benchmarks for operations exported from Streamly.Internal.Data.Scanl.Container. module Scanl.Container (benchmarks) where +-- import Data.IntSet (IntSet) import Data.IORef (IORef, newIORef, readIORef, modifyIORef) import Data.Map.Strict (Map) +-- import Data.Set (Set) +-- import Data.STRef (STRef) import Streamly.Internal.Data.Scanl (Scanl(..)) import Streamly.Internal.Data.Stream (Stream) +-- import Streamly.Internal.Data.Tuple.Strict (Tuple', Tuple3') import System.IO.Unsafe (unsafePerformIO) import System.Random (randomRIO) @@ -40,15 +31,10 @@ import qualified Streamly.Internal.Data.Fold as FL import qualified Streamly.Internal.Data.Scanl as Scanl import qualified Streamly.Internal.Data.Stream as Stream +import Fusion.Plugin.Types import Streamly.Benchmark.Common import Test.Tasty.Bench -#ifdef INSPECTION -import GHC.Types (SPEC(..)) -import Streamly.Internal.Data.Stream (Step(..)) -import Test.Inspection -#endif - ------------------------------------------------------------------------------- -- Helpers ------------------------------------------------------------------------------- @@ -97,26 +83,44 @@ getScanl k = do -- Set operations ------------------------------------------------------------------------------- +-- {-# ANN toSet (PermitTypes [''Int,''Set,''STRef,''(,)]) #-} +{-# ANN toSet (PermitTypeClasses []) #-} +{-# ANN toSet (MaxCoreSize 1000) #-} {-# NOINLINE toSet #-} toSet :: Int -> IO () toSet n = withPostscanl n Scanl.toSet +-- {-# ANN toIntSet (PermitTypes [''Int,''STRef,''IntSet,''(,)]) #-} +{-# ANN toIntSet (PermitTypeClasses []) #-} +{-# ANN toIntSet (MaxCoreSize 1000) #-} {-# NOINLINE toIntSet #-} toIntSet :: Int -> IO () toIntSet n = withPostscanl n Scanl.toIntSet +-- {-# ANN countDistinct (PermitTypes [''Int,''STRef,''Set,''(,)]) #-} +{-# ANN countDistinct (PermitTypeClasses []) #-} +{-# ANN countDistinct (MaxCoreSize 1000) #-} {-# NOINLINE countDistinct #-} countDistinct :: Int -> IO () countDistinct n = withPostscanl n Scanl.countDistinct +-- {-# ANN countDistinctInt (PermitTypes [''Int,''STRef,''IntSet,''(,)]) #-} +{-# ANN countDistinctInt (PermitTypeClasses []) #-} +{-# ANN countDistinctInt (MaxCoreSize 1000) #-} {-# NOINLINE countDistinctInt #-} countDistinctInt :: Int -> IO () countDistinctInt n = withPostscanl n Scanl.countDistinctInt +-- {-# ANN nub (PermitTypes [''Int,''STRef,''Set,''Maybe,''Tuple',''(,)]) #-} +{-# ANN nub (PermitTypeClasses []) #-} +{-# ANN nub (MaxCoreSize 1000) #-} {-# NOINLINE nub #-} nub :: Int -> IO () nub n = withPostscanl n Scanl.nub +-- {-# ANN nubInt (PermitTypes [''Int,''STRef,''IntSet,''(,)]) #-} +{-# ANN nubInt (PermitTypeClasses []) #-} +{-# ANN nubInt (MaxCoreSize 1000) #-} {-# NOINLINE nubInt #-} nubInt :: Int -> IO () nubInt n = withPostscanl n Scanl.nubInt @@ -125,6 +129,10 @@ nubInt n = withPostscanl n Scanl.nubInt -- Demultiplexing ------------------------------------------------------------------------------- +-- {-# ANN demuxIOOneShot (PermitTypes [''Int,''STRef,''IORef,''Map,''Scanl, +-- ''FL.Step, ''Scanl.Step,''(,)]) #-} +{-# ANN demuxIOOneShot (PermitTypeClasses []) #-} +{-# ANN demuxIOOneShot (MaxCoreSize 2000) #-} {-# NOINLINE demuxIOOneShot #-} demuxIOOneShot :: Int -> IO () demuxIOOneShot len = @@ -132,6 +140,10 @@ demuxIOOneShot len = Stream.fold FL.drain . Stream.postscanl (Scanl.demuxIO (getKey 64) getScanl) +-- {-# ANN demuxIOSum (PermitTypes +-- [''Int,''STRef,''IORef,''Map,''Scanl,''FL.Step,''Scanl.Step,''(,)]) #-} +{-# ANN demuxIOSum (PermitTypeClasses []) #-} +{-# ANN demuxIOSum (MaxCoreSize 1000) #-} {-# NOINLINE demuxIOSum #-} demuxIOSum :: Int -> IO () demuxIOSum len = @@ -140,10 +152,9 @@ demuxIOSum len = . Stream.postscanl (Scanl.demuxIO (getKey 64) (const (pure (Just Scanl.sum)))) -#ifdef INSPECTION -inspect $ 'demuxIOSum `hasNoType` ''SPEC -#endif - +-- {-# ANN demuxSum (PermitTypes [''Int,''STRef,''IO,''Map,''Scanl,''FL.Step,''Scanl.Step,''(,)]) #-} +{-# ANN demuxSum (PermitTypeClasses []) #-} +{-# ANN demuxSum (MaxCoreSize 1000) #-} {-# NOINLINE demuxSum #-} demuxSum :: Int -> IO () demuxSum len = @@ -152,6 +163,10 @@ demuxSum len = . Stream.postscanl (Scanl.demux (getKey 64) (const (pure (Just Scanl.sum)))) +-- {-# ANN demuxGenericSum (PermitTypes +-- [''Int,''STRef,''Map,''Maybe,''Scanl,''FL.Step,''Scanl.Step,''(,)]) #-} +{-# ANN demuxGenericSum (PermitTypeClasses []) #-} +{-# ANN demuxGenericSum (MaxCoreSize 1000) #-} {-# NOINLINE demuxGenericSum #-} demuxGenericSum :: Int -> IO () demuxGenericSum len = @@ -161,6 +176,10 @@ demuxGenericSum len = (Scanl.demuxGeneric (getKey 64) (const (pure (Just Scanl.sum))) :: Scanl IO Int (IO (Map Int Int), Maybe (Int, Int))) +-- {-# ANN demuxGenericIOSum (PermitTypes +-- [''Int,''STRef,''Map,''Maybe,''Scanl,''FL.Step,''Scanl.Step,''(,)]) #-} +{-# ANN demuxGenericIOSum (PermitTypeClasses []) #-} +{-# ANN demuxGenericIOSum (MaxCoreSize 1000) #-} {-# NOINLINE demuxGenericIOSum #-} demuxGenericIOSum :: Int -> IO () demuxGenericIOSum len = @@ -174,6 +193,9 @@ demuxGenericIOSum len = -- Classifying ------------------------------------------------------------------------------- +-- {-# ANN classifyLimitedSum (PermitTypes [''Int,''STRef,''IORef,''Map,''Set,''Tuple',''(,)]) #-} +{-# ANN classifyLimitedSum (PermitTypeClasses []) #-} +{-# ANN classifyLimitedSum (MaxCoreSize 1000) #-} {-# NOINLINE classifyLimitedSum #-} classifyLimitedSum :: Int -> IO () classifyLimitedSum len = @@ -181,11 +203,9 @@ classifyLimitedSum len = Stream.fold FL.drain . Stream.postscanl (Scanl.classifyIO (getKey 64) (limitedSum 100)) -#ifdef INSPECTION -inspect $ 'classifyLimitedSum `hasNoType` ''FL.Step -inspect $ 'classifyLimitedSum `hasNoType` ''SPEC -#endif - +-- {-# ANN classifyIOSum (PermitTypes [''Int,''STRef,''IORef,''Map,''Tuple',''(,)]) #-} +{-# ANN classifyIOSum (PermitTypeClasses []) #-} +{-# ANN classifyIOSum (MaxCoreSize 1000) #-} {-# NOINLINE classifyIOSum #-} classifyIOSum :: Int -> IO () classifyIOSum len = @@ -193,11 +213,9 @@ classifyIOSum len = Stream.fold FL.drain . Stream.postscanl (Scanl.classifyIO (getKey 64) Scanl.sum) -#ifdef INSPECTION -inspect $ 'classifyIOSum `hasNoType` ''FL.Step -inspect $ 'classifyIOSum `hasNoType` ''SPEC -#endif - +-- {-# ANN classifySum (PermitTypes [''Int,''STRef,''Map,''Tuple',''(,)]) #-} +{-# ANN classifySum (PermitTypeClasses []) #-} +{-# ANN classifySum (MaxCoreSize 1000) #-} {-# NOINLINE classifySum #-} classifySum :: Int -> IO () classifySum len = @@ -205,6 +223,9 @@ classifySum len = Stream.fold FL.drain . Stream.postscanl (Scanl.classify (getKey 64) Scanl.sum) +-- {-# ANN classifyGenericSum (PermitTypes [''Int,''STRef,''Map,''Maybe,''Set,''Tuple',''Tuple3',''(,)]) #-} +{-# ANN classifyGenericSum (PermitTypeClasses []) #-} +{-# ANN classifyGenericSum (MaxCoreSize 1000) #-} {-# NOINLINE classifyGenericSum #-} classifyGenericSum :: Int -> IO () classifyGenericSum len = @@ -214,6 +235,9 @@ classifyGenericSum len = (Scanl.classifyGeneric (getKey 64) Scanl.sum :: Scanl IO Int (IO (Map Int Int), Maybe (Int, Int))) +-- {-# ANN classifyGenericIOSum (PermitTypes [''Int,''STRef,''Map,''Maybe,''Set,''Tuple',''Tuple3',''(,)]) #-} +{-# ANN classifyGenericIOSum (PermitTypeClasses []) #-} +{-# ANN classifyGenericIOSum (MaxCoreSize 1000) #-} {-# NOINLINE classifyGenericIOSum #-} classifyGenericIOSum :: Int -> IO () classifyGenericIOSum len = diff --git a/benchmark/streamly-benchmarks.cabal b/benchmark/streamly-benchmarks.cabal index 919228cd8a..729a6f7e2d 100644 --- a/benchmark/streamly-benchmarks.cabal +++ b/benchmark/streamly-benchmarks.cabal @@ -155,7 +155,12 @@ common optimization-options ghc-options: -fno-ignore-asserts if flag(fusion-plugin) && !impl(ghcjs) && !impl(ghc < 8.6) - ghc-options: -fplugin Fusion.Plugin -ddump-simpl -ddump-to-file -dsuppress-all + ghc-options: + -fplugin Fusion.Plugin + -fplugin-opt=Fusion.Plugin:werror + -ddump-simpl + -ddump-to-file + -dsuppress-all else ghc-options: -O0 From ca32f398a213b892a7e0211a7ce525a83ded7431 Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Sat, 11 Jul 2026 23:19:30 +0530 Subject: [PATCH 6/6] Add missing test file to distribution --- streamly.cabal | 1 + 1 file changed, 1 insertion(+) diff --git a/streamly.cabal b/streamly.cabal index 0fe3d48d1a..c682d4af82 100644 --- a/streamly.cabal +++ b/streamly.cabal @@ -154,6 +154,7 @@ extra-source-files: test/Streamly/Test/Data/MutByteArray/*.hs test/lib/Streamly/Test/Common.hs test/lib/Streamly/Test/Control/Exception/Common.hs + test/lib/Streamly/Test/Data/Scanl/Common.hs test/lib/Streamly/Test/Prelude/Common.hs test/lib/Streamly/Test/Data/Parser/*.hs test/streamly-tests.cabal