Merge pull request #1751

This commit is contained in:
Harendra Kumar 2022-08-06 23:14:10 +05:30
commit f5ef71303e
17 changed files with 1144 additions and 482 deletions

View File

@ -29,11 +29,11 @@ jobs:
Data.Stream.StreamDK
Data.Stream.StreamK:6
Data.Unfold
Data.Stream
FileSystem.Handle
Prelude.Ahead
Prelude.Async:12
Prelude.Parallel
Prelude.Serial
Prelude.WAsync:6
Prelude.WSerial
Prelude.ZipAsync

View File

@ -26,12 +26,13 @@
- ignore: {name: "Use fmap"}
# Warnings ignored in specific places
- ignore: {name: "Use ++", within: Serial.Transformation}
- ignore: {name: "Use mapM", within: Serial.Transformation}
- ignore: {name: "Use traverse", within: Serial.Transformation}
- ignore: {name: "Redundant <*", within: Serial.NestedStream}
- ignore: {name: "Use ++", within: Serial.NestedStream}
- ignore: {name: "Use ++", within: Stream.Transform}
- ignore: {name: "Use mapM", within: Stream.Transform}
- ignore: {name: "Use traverse", within: Stream.Transform}
- ignore: {name: "Redundant <*", within: Stream.Expand}
- ignore: {name: "Use ++", within: Stream.Reduce}
- ignore: {name: "Use ++", within: Stream.Split}
- ignore: {name: "Redundant bracket", within: Stream.Split}
- ignore: {name: "Use isDigit", within: Streamly.Internal.Unicode.Char.Parser}
# Specify additional command line arguments

View File

@ -1,5 +1,5 @@
-- |
-- Module : Serial
-- Module : Data.Stream
-- Copyright : (c) 2018 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -13,19 +13,21 @@ module Main (main) where
import Streamly.Benchmark.Common.Handle (mkHandleBenchEnv)
import qualified Serial.Elimination as Elimination
import qualified Serial.Exceptions as Exceptions
import qualified Serial.Generation as Generation
import qualified Serial.NestedStream as NestedStream
import qualified Serial.Split as Split
import qualified Serial.Transformation as Transformation
import qualified Serial.NestedFold as NestedFold
import qualified Serial.Lift as Lift
import qualified Stream.Eliminate as Elimination
import qualified Stream.Exceptions as Exceptions
import qualified Stream.Expand as NestedStream
import qualified Stream.Generate as Generation
import qualified Stream.Lift as Lift
import qualified Stream.Reduce as NestedFold
#ifdef USE_PRELUDE
import qualified Stream.Split as Split
#endif
import qualified Stream.Transform as Transformation
import Streamly.Benchmark.Common
moduleName :: String
moduleName = "Prelude.Serial"
moduleName = "Data.Stream"
-------------------------------------------------------------------------------
-- Main
@ -45,7 +47,9 @@ main = do
[ Generation.benchmarks moduleName size
, Elimination.benchmarks moduleName size
, Exceptions.benchmarks moduleName env size
#ifdef USE_PRELUDE
, Split.benchmarks moduleName env
#endif
, Transformation.benchmarks moduleName size
, NestedFold.benchmarks moduleName size
, Lift.benchmarks moduleName size

View File

@ -0,0 +1,472 @@
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- |
-- Module : Stream.Common
-- Copyright : (c) 2018 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
module Stream.Common
( MonadAsync
-- Generation
, enumerateFromTo
, replicate
, unfoldrM
, fromListM
, append
, append2
-- Elimination
, drain
, foldl'
, scanl'
-- Benchmark stream generation
, sourceUnfoldr
, sourceUnfoldrM
, sourceUnfoldrAction
, sourceConcatMapId
, sourceFromFoldable
, sourceFromFoldableM
-- Benchmark stream elimination
, benchIOSink
, benchIOSrc
-- Benchmarking functions
, concatStreamsWith
, concatPairsWith
, apDiscardFst
, apDiscardSnd
, apLiftA2
, toNullAp
, monadThen
, toNullM
, toNullM3
, filterAllOutM
, filterAllInM
, filterSome
, breakAfterSome
, toListM
, toListSome
, composeN
, mapN
, mapM
, transformMapM
, transformComposeMapM
, transformTeeMapM
, transformZipMapM
)
where
import Control.Applicative (liftA2)
import Control.Exception (try)
import GHC.Exception (ErrorCall)
import Streamly.Internal.Data.Stream (Stream)
import System.Random (randomRIO)
import qualified Streamly.Internal.Data.Fold as Fold
import qualified Streamly.Internal.Data.Pipe as Pipe
#ifdef USE_PRELUDE
import Streamly.Prelude (foldl', scanl')
import qualified Streamly.Internal.Data.Stream.IsStream as Stream
import qualified Streamly.Prelude as Stream
import Streamly.Benchmark.Prelude
( composeN, sourceUnfoldr, sourceUnfoldr, sourceFromFoldable
, sourceFromFoldableM, sourceUnfoldrAction, sourceConcatMapId, benchIOSink
, concatStreamsWith, concatPairsWith
)
#else
import Control.DeepSeq (NFData)
import Streamly.Internal.Data.Stream (unfold)
import qualified Streamly.Internal.Data.Stream as Stream
import qualified Streamly.Internal.Data.Unfold as Unfold
#endif
import Gauge
import Prelude hiding (mapM, replicate)
#ifdef USE_PRELUDE
type MonadAsync m = Stream.MonadAsync m
#else
type MonadAsync = Monad
#endif
{-# INLINE append #-}
append :: Stream m a -> Stream m a -> Stream m a
#ifdef USE_PRELUDE
append = Stream.serial
#else
append = Stream.append
#endif
{-# INLINE append2 #-}
append2 :: Monad m => Stream m a -> Stream m a -> Stream m a
#ifdef USE_PRELUDE
append2 = Stream.append
#else
append2 = Stream.append2
#endif
{-# INLINE drain #-}
drain :: Monad m => Stream m a -> m ()
drain = Stream.fold Fold.drain
{-# INLINE enumerateFromTo #-}
enumerateFromTo :: Monad m => Int -> Int -> Stream m Int
#ifdef USE_PRELUDE
enumerateFromTo = Stream.enumerateFromTo
#else
enumerateFromTo from to = Stream.unfold Unfold.enumerateFromTo (from, to)
#endif
{-# INLINE replicate #-}
replicate :: Monad m => Int -> a -> Stream m a
#ifdef USE_PRELUDE
replicate = Stream.replicate
#else
replicate n = Stream.unfold (Unfold.replicateM n) . return
#endif
{-# INLINE unfoldrM #-}
unfoldrM :: MonadAsync m => (b -> m (Maybe (a, b))) -> b -> Stream m a
#ifdef USE_PRELUDE
unfoldrM = Stream.unfoldrM
#else
unfoldrM step = Stream.unfold (Unfold.unfoldrM step)
#endif
{-# INLINE fromListM #-}
fromListM :: MonadAsync m => [m a] -> Stream m a
#ifdef USE_PRELUDE
fromListM = Stream.fromListM
#else
fromListM = Stream.unfold Unfold.fromListM
#endif
{-# INLINE sourceUnfoldrM #-}
sourceUnfoldrM :: MonadAsync m => Int -> Int -> Stream m Int
sourceUnfoldrM count start = unfoldrM step start
where
step cnt =
if cnt > start + count
then return Nothing
else return (Just (cnt, cnt + 1))
#ifndef USE_PRELUDE
{-# INLINE sourceUnfoldr #-}
sourceUnfoldr :: Monad m => Int -> Int -> Stream m Int
sourceUnfoldr count start = unfold (Unfold.unfoldr step) start
where
step cnt =
if cnt > start + count
then Nothing
else Just (cnt, cnt + 1)
{-# INLINE sourceUnfoldrAction #-}
sourceUnfoldrAction :: (Monad m1, Monad m) => Int -> Int -> Stream m (m1 Int)
sourceUnfoldrAction value n = unfold (Unfold.unfoldr step) n
where
step cnt =
if cnt > n + value
then Nothing
else Just (return cnt, cnt + 1)
{-# INLINE sourceFromFoldable #-}
sourceFromFoldable :: Int -> Int -> Stream m Int
sourceFromFoldable value n = Stream.fromFoldable [n..n+value]
{-# INLINE sourceFromFoldableM #-}
sourceFromFoldableM :: Monad m => Int -> Int -> Stream m Int
sourceFromFoldableM value n = Stream.fromFoldableM (fmap return [n..n+value])
{-# INLINE benchIOSink #-}
benchIOSink
:: (NFData b)
=> Int -> String -> (Stream IO Int -> IO b) -> Benchmark
benchIOSink value name f =
bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldrM value
#endif
-- | Takes a source, and uses it with a default drain/fold method.
{-# INLINE benchIOSrc #-}
benchIOSrc
:: String
-> (Int -> Stream IO a)
-> Benchmark
benchIOSrc name f =
bench name $ nfIO $ randomRIO (1,1) >>= drain . f
#ifndef USE_PRELUDE
{-# INLINE concatStreamsWith #-}
concatStreamsWith
:: (Stream IO Int -> Stream IO Int -> Stream IO Int)
-> Int
-> Int
-> Int
-> IO ()
concatStreamsWith op outer inner n =
drain $ Stream.concatMapWith op
(sourceUnfoldrM inner)
(sourceUnfoldrM outer n)
{-# INLINE concatPairsWith #-}
concatPairsWith
:: (Stream IO Int -> Stream IO Int -> Stream IO Int)
-> Int
-> Int
-> Int
-> IO ()
concatPairsWith op outer inner n =
drain $ Stream.concatPairsWith op
(sourceUnfoldrM inner)
(sourceUnfoldrM outer n)
{-# INLINE sourceConcatMapId #-}
sourceConcatMapId :: (Monad m)
=> Int -> Int -> Stream m (Stream m Int)
sourceConcatMapId value n =
Stream.fromFoldable $ fmap (Stream.fromEffect . return) [n..n+value]
#endif
{-# INLINE apDiscardFst #-}
apDiscardFst :: MonadAsync m =>
Int -> Int -> m ()
apDiscardFst linearCount start = drain $
sourceUnfoldrM nestedCount2 start
*> sourceUnfoldrM nestedCount2 start
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE apDiscardSnd #-}
apDiscardSnd :: MonadAsync m => Int -> Int -> m ()
apDiscardSnd linearCount start = drain $
sourceUnfoldrM nestedCount2 start
<* sourceUnfoldrM nestedCount2 start
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE apLiftA2 #-}
apLiftA2 :: MonadAsync m => Int -> Int -> m ()
apLiftA2 linearCount start = drain $
liftA2 (+) (sourceUnfoldrM nestedCount2 start)
(sourceUnfoldrM nestedCount2 start)
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE toNullAp #-}
toNullAp :: MonadAsync m => Int -> Int -> m ()
toNullAp linearCount start = drain $
(+) <$> sourceUnfoldrM nestedCount2 start
<*> sourceUnfoldrM nestedCount2 start
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE monadThen #-}
monadThen :: MonadAsync m => Int -> Int -> m ()
monadThen linearCount start = drain $ do
sourceUnfoldrM nestedCount2 start >>
sourceUnfoldrM nestedCount2 start
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE toNullM #-}
toNullM :: MonadAsync m => Int -> Int -> m ()
toNullM linearCount start = drain $ do
x <- sourceUnfoldrM nestedCount2 start
y <- sourceUnfoldrM nestedCount2 start
return $ x + y
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE toNullM3 #-}
toNullM3 :: MonadAsync m => Int -> Int -> m ()
toNullM3 linearCount start = drain $ do
x <- sourceUnfoldrM nestedCount3 start
y <- sourceUnfoldrM nestedCount3 start
z <- sourceUnfoldrM nestedCount3 start
return $ x + y + z
where
nestedCount3 = round (fromIntegral linearCount**(1/3::Double))
{-# INLINE filterAllOutM #-}
filterAllOutM :: MonadAsync m => Int -> Int -> m ()
filterAllOutM linearCount start = drain $ do
x <- sourceUnfoldrM nestedCount2 start
y <- sourceUnfoldrM nestedCount2 start
let s = x + y
if s < 0
then return s
else Stream.nil
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE filterAllInM #-}
filterAllInM :: MonadAsync m => Int -> Int -> m ()
filterAllInM linearCount start = drain $ do
x <- sourceUnfoldrM nestedCount2 start
y <- sourceUnfoldrM nestedCount2 start
let s = x + y
if s > 0
then return s
else Stream.nil
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE filterSome #-}
filterSome :: MonadAsync m => Int -> Int -> m ()
filterSome linearCount start = drain $ do
x <- sourceUnfoldrM nestedCount2 start
y <- sourceUnfoldrM nestedCount2 start
let s = x + y
if s > 1100000
then return s
else Stream.nil
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE breakAfterSome #-}
breakAfterSome :: Int -> Int -> IO ()
breakAfterSome linearCount start = do
(_ :: Either ErrorCall ()) <- try $ drain $ do
x <- sourceUnfoldrM nestedCount2 start
y <- sourceUnfoldrM nestedCount2 start
let s = x + y
if s > 1100000
then error "break"
else return s
return ()
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
{-# INLINE toListM #-}
toListM :: MonadAsync m => Int -> Int -> m [Int]
toListM linearCount start = Stream.fold Fold.toList $ do
x <- sourceUnfoldrM nestedCount2 start
y <- sourceUnfoldrM nestedCount2 start
return $ x + y
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
-- Taking a specified number of elements is very expensive in logict so we have
-- a test to measure the same.
{-# INLINE toListSome #-}
toListSome :: MonadAsync m => Int -> Int -> m [Int]
toListSome linearCount start =
Stream.fold Fold.toList $ Stream.take 10000 $ do
x <- sourceUnfoldrM nestedCount2 start
y <- sourceUnfoldrM nestedCount2 start
return $ x + y
where
nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
#ifndef USE_PRELUDE
{-# INLINE composeN #-}
composeN ::
(Monad m)
=> Int
-> (Stream m Int -> Stream m Int)
-> Stream m Int
-> m ()
composeN n f =
case n of
1 -> drain . f
2 -> drain . f . f
3 -> drain . f . f . f
4 -> drain . f . f . f . f
_ -> undefined
#endif
{-# INLINE mapN #-}
mapN ::
Monad m
=> Int
-> Stream m Int
-> m ()
mapN n = composeN n $ fmap (+ 1)
{-# INLINE mapM #-}
mapM ::
MonadAsync m
=> Int
-> Stream m Int
-> m ()
mapM n = composeN n $ Stream.mapM return
#ifndef USE_PRELUDE
foldl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> m b
foldl' f z = Stream.fold (Fold.foldl' f z)
scanl' :: Monad m => (b -> a -> b) -> b -> Stream m a -> Stream m b
scanl' f z = Stream.scan (Fold.foldl' f z)
#endif
{-# INLINE transformMapM #-}
transformMapM ::
(Monad m)
=> Int
-> Stream m Int
-> m ()
transformMapM n = composeN n $ Stream.transform (Pipe.mapM return)
{-# INLINE transformComposeMapM #-}
transformComposeMapM ::
(Monad m)
=> Int
-> Stream m Int
-> m ()
transformComposeMapM n =
composeN n $
Stream.transform
(Pipe.mapM (\x -> return (x + 1)) `Pipe.compose`
Pipe.mapM (\x -> return (x + 2)))
{-# INLINE transformTeeMapM #-}
transformTeeMapM ::
(Monad m)
=> Int
-> Stream m Int
-> m ()
transformTeeMapM n =
composeN n $
Stream.transform
(Pipe.mapM (\x -> return (x + 1)) `Pipe.tee`
Pipe.mapM (\x -> return (x + 2)))
{-# INLINE transformZipMapM #-}
transformZipMapM ::
(Monad m)
=> Int
-> Stream m Int
-> m ()
transformZipMapM n =
composeN n $
Stream.transform
(Pipe.zipWith
(+)
(Pipe.mapM (\x -> return (x + 1)))
(Pipe.mapM (\x -> return (x + 2))))

View File

@ -1,5 +1,5 @@
-- |
-- Module : Serial.Elimination
-- Module : Stream.Eliminate
-- Copyright : (c) 2018 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -18,7 +18,7 @@
{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
#endif
module Serial.Elimination (benchmarks) where
module Stream.Eliminate (benchmarks) where
import Control.DeepSeq (NFData(..))
import Data.Functor.Identity (Identity, runIdentity)
@ -33,21 +33,37 @@ import Test.Inspection
import qualified Streamly.Internal.Data.Stream.StreamD as D
#endif
import qualified Streamly.Prelude as S
import qualified Streamly.Internal.Data.Stream.IsStream as Internal
import qualified Streamly.Internal.Data.Fold as Fold
#ifdef USE_PRELUDE
import qualified Streamly.Internal.Data.Stream.IsStream as S
#else
import qualified Streamly.Internal.Data.Stream as S
#endif
import Gauge
import Streamly.Prelude (SerialT, IsStream, fromSerial)
import Streamly.Benchmark.Common
-- XXX Replace SerialT with Stream
import Streamly.Internal.Data.Stream.Serial (SerialT)
#ifdef USE_PRELUDE
import Streamly.Prelude (fromSerial)
import Streamly.Benchmark.Prelude
#else
import Stream.Common
( sourceUnfoldr
, sourceUnfoldrM
, sourceUnfoldrAction
, benchIOSink
)
#endif
import Streamly.Benchmark.Common
import Prelude hiding (length, sum, or, and, any, all, notElem, elem, (!!),
lookup, repeat, minimum, maximum, product, last, mapM_, init)
import qualified Prelude
#ifdef USE_PRELUDE
{-# INLINE repeat #-}
repeat :: (Monad m, S.IsStream t) => Int -> Int -> t m Int
repeat count = S.take count . S.repeat
#endif
-------------------------------------------------------------------------------
-- Elimination
@ -60,76 +76,76 @@ repeat count = S.take count . S.repeat
{-# INLINE foldableFoldl' #-}
foldableFoldl' :: Int -> Int -> Int
foldableFoldl' value n =
F.foldl' (+) 0 (sourceUnfoldr value n :: S.SerialT Identity Int)
F.foldl' (+) 0 (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableFoldrElem #-}
foldableFoldrElem :: Int -> Int -> Bool
foldableFoldrElem value n =
F.foldr (\x xs -> x == value || xs)
False
(sourceUnfoldr value n :: S.SerialT Identity Int)
(sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableSum #-}
foldableSum :: Int -> Int -> Int
foldableSum value n =
Prelude.sum (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.sum (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableProduct #-}
foldableProduct :: Int -> Int -> Int
foldableProduct value n =
Prelude.product (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.product (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE _foldableNull #-}
_foldableNull :: Int -> Int -> Bool
_foldableNull value n =
Prelude.null (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.null (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableElem #-}
foldableElem :: Int -> Int -> Bool
foldableElem value n =
value `Prelude.elem` (sourceUnfoldr value n :: S.SerialT Identity Int)
value `Prelude.elem` (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableNotElem #-}
foldableNotElem :: Int -> Int -> Bool
foldableNotElem value n =
value `Prelude.notElem` (sourceUnfoldr value n :: S.SerialT Identity Int)
value `Prelude.notElem` (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableFind #-}
foldableFind :: Int -> Int -> Maybe Int
foldableFind value n =
F.find (== (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
F.find (== (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableAll #-}
foldableAll :: Int -> Int -> Bool
foldableAll value n =
Prelude.all (<= (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.all (<= (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableAny #-}
foldableAny :: Int -> Int -> Bool
foldableAny value n =
Prelude.any (> (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.any (> (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableAnd #-}
foldableAnd :: Int -> Int -> Bool
foldableAnd value n =
Prelude.and $ S.map
(<= (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.and $ fmap
(<= (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableOr #-}
foldableOr :: Int -> Int -> Bool
foldableOr value n =
Prelude.or $ S.map
(> (value + 1)) (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.or $ fmap
(> (value + 1)) (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableLength #-}
foldableLength :: Int -> Int -> Int
foldableLength value n =
Prelude.length (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.length (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableMin #-}
foldableMin :: Int -> Int -> Int
foldableMin value n =
Prelude.minimum (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.minimum (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE ordInstanceMin #-}
ordInstanceMin :: SerialT Identity Int -> SerialT Identity Int
@ -138,12 +154,12 @@ ordInstanceMin src = min src src
{-# INLINE foldableMax #-}
foldableMax :: Int -> Int -> Int
foldableMax value n =
Prelude.maximum (sourceUnfoldr value n :: S.SerialT Identity Int)
Prelude.maximum (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableMinBy #-}
foldableMinBy :: Int -> Int -> Int
foldableMinBy value n =
F.minimumBy compare (sourceUnfoldr value n :: S.SerialT Identity Int)
F.minimumBy compare (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableListMinBy #-}
foldableListMinBy :: Int -> Int -> Int
@ -152,27 +168,27 @@ foldableListMinBy value n = F.minimumBy compare [1..value+n]
{-# INLINE foldableMaxBy #-}
foldableMaxBy :: Int -> Int -> Int
foldableMaxBy value n =
F.maximumBy compare (sourceUnfoldr value n :: S.SerialT Identity Int)
F.maximumBy compare (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableToList #-}
foldableToList :: Int -> Int -> [Int]
foldableToList value n =
F.toList (sourceUnfoldr value n :: S.SerialT Identity Int)
F.toList (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableMapM_ #-}
foldableMapM_ :: Monad m => Int -> Int -> m ()
foldableMapM_ value n =
F.mapM_ (\_ -> return ()) (sourceUnfoldr value n :: S.SerialT Identity Int)
F.mapM_ (\_ -> return ()) (sourceUnfoldr value n :: SerialT Identity Int)
{-# INLINE foldableSequence_ #-}
foldableSequence_ :: Int -> Int -> IO ()
foldableSequence_ value n =
F.sequence_ (sourceUnfoldrAction value n :: S.SerialT Identity (IO Int))
F.sequence_ (sourceUnfoldrAction value n :: SerialT Identity (IO Int))
{-# INLINE _foldableMsum #-}
_foldableMsum :: Int -> Int -> IO Int
_foldableMsum value n =
F.msum (sourceUnfoldrAction value n :: S.SerialT Identity (IO Int))
F.msum (sourceUnfoldrAction value n :: SerialT Identity (IO Int))
{-# INLINE showInstance #-}
showInstance :: SerialT Identity Int -> String
@ -240,8 +256,8 @@ benchPureSink value name = benchPure name (sourceUnfoldr value)
{-# INLINE benchHoistSink #-}
benchHoistSink
:: (IsStream t, NFData b)
=> Int -> String -> (t Identity Int -> IO b) -> Benchmark
:: (NFData b)
=> Int -> String -> (SerialT Identity Int -> IO b) -> Benchmark
benchHoistSink value name f =
bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldr value
@ -249,8 +265,8 @@ benchHoistSink value name f =
-- we can't use it as it requires MonadAsync constraint.
{-# INLINE benchIdentitySink #-}
benchIdentitySink
:: (IsStream t, NFData b)
=> Int -> String -> (t Identity Int -> Identity b) -> Benchmark
:: (NFData b)
=> Int -> String -> (SerialT Identity Int -> Identity b) -> Benchmark
benchIdentitySink value name f = bench name $ nf (f . sourceUnfoldr value) 1
-------------------------------------------------------------------------------
@ -265,6 +281,7 @@ uncons s = do
Nothing -> return ()
Just (_, t) -> uncons t
#ifdef USE_PRELUDE
{-# INLINE init #-}
init :: Monad m => SerialT m a -> m ()
init s = S.init s >>= Prelude.mapM_ S.drain
@ -272,6 +289,7 @@ init s = S.init s >>= Prelude.mapM_ S.drain
{-# INLINE mapM_ #-}
mapM_ :: Monad m => SerialT m Int -> m ()
mapM_ = S.mapM_ (\_ -> return ())
#endif
{-# INLINE foldrMElem #-}
foldrMElem :: Monad m => Int -> SerialT m Int -> m Bool
@ -291,6 +309,7 @@ foldrToStream = S.foldr S.cons S.nil
foldrMBuild :: Monad m => SerialT m Int -> m [Int]
foldrMBuild = S.foldrM (\x xs -> (x :) <$> xs) (return [])
#ifdef USE_PRELUDE
{-# INLINE foldl'Reduce #-}
foldl'Reduce :: Monad m => SerialT m Int -> m Int
foldl'Reduce = S.foldl' (+) 0
@ -393,38 +412,43 @@ drainWhile = S.drainWhile (const True)
{-# INLINE (!!) #-}
(!!) :: Monad m => Int -> SerialT m Int -> m (Maybe Int)
(!!) = flip (Internal.!!)
(!!) = flip (S.!!)
{-# INLINE lookup #-}
lookup :: Monad m => Int -> SerialT m Int -> m (Maybe Int)
lookup val = S.lookup val . S.map (\x -> (x, x))
#endif
o_1_space_elimination_folds :: Int -> [Benchmark]
o_1_space_elimination_folds value =
[ bgroup "elimination"
-- Basic folds
[ bgroup "reduce"
[
#ifdef USE_PRELUDE
bgroup "reduce"
[ bgroup
"IO"
[ benchIOSink value "foldl'" foldl'Reduce
, benchIOSink value "foldl1'" foldl1'Reduce
, benchIOSink value "foldlM'" foldlM'Reduce
]
, bgroup
"Identity"
[ benchIdentitySink value "foldl'" foldl'Reduce
, benchIdentitySink value "foldl1'" foldl1'Reduce
, benchIdentitySink value "foldlM'" foldlM'Reduce
]
]
, bgroup "build"
] ,
#endif
bgroup "build"
[ bgroup "IO"
[ benchIOSink value "foldrMElem" (foldrMElem value)
]
, bgroup "Identity"
[ benchIdentitySink value "foldrMElem" (foldrMElem value)
, benchIdentitySink value "foldrToStreamLength"
(S.length . runIdentity . foldrToStream)
(S.fold Fold.length . runIdentity . foldrToStream)
, benchPureSink value "foldrMToListLength"
(Prelude.length . runIdentity . foldrMBuild)
]
@ -432,6 +456,9 @@ o_1_space_elimination_folds value =
-- deconstruction
, benchIOSink value "uncons" uncons
, benchHoistSink value "length . generally"
(S.fold Fold.length . S.generally)
#ifdef USE_PRELUDE
, benchIOSink value "init" init
-- draining
@ -445,8 +472,6 @@ o_1_space_elimination_folds value =
-- , benchIOSink value "head" head
, benchIOSink value "last" last
, benchIOSink value "length" length
, benchHoistSink value "length . generally"
(length . Internal.generally)
, benchIOSink value "sum" sum
, benchIOSink value "product" product
, benchIOSink value "maximumBy" maximumBy
@ -470,6 +495,7 @@ o_1_space_elimination_folds value =
, benchIOSink value "any" (any value)
, benchIOSink value "and" (and value)
, benchIOSink value "or" (or value)
#endif
-- length is used to check for foldr/build fusion
, benchPureSink value "length . IsList.toList" (Prelude.length . GHC.toList)
@ -480,6 +506,7 @@ o_1_space_elimination_folds value =
-- Buffered Transformations by fold
-------------------------------------------------------------------------------
#ifdef USE_PRELUDE
{-# INLINE foldl'Build #-}
foldl'Build :: Monad m => SerialT m Int -> m [Int]
foldl'Build = S.foldl' (flip (:)) []
@ -499,6 +526,7 @@ o_n_heap_elimination_foldl value =
, benchIdentitySink value "foldlM'/build/Identity" foldlM'Build
]
]
#endif
-- For comparisons
{-# INLINE showInstanceList #-}
@ -534,13 +562,14 @@ o_n_space_elimination_foldr value =
]
]
#ifdef USE_PRELUDE
o_n_heap_elimination_toList :: Int -> [Benchmark]
o_n_heap_elimination_toList value =
[ bgroup "toList"
-- Converting the stream to a list or pure stream in a strict monad
[ benchIOSink value "toListRev" Internal.toListRev
[ benchIOSink value "toListRev" S.toListRev
, benchIOSink value "toStreamRev"
(Internal.toStreamRev :: (SerialT IO Int -> IO (SerialT Identity Int)))
(S.toStreamRev :: (SerialT IO Int -> IO (SerialT Identity Int)))
]
]
@ -550,9 +579,10 @@ o_n_space_elimination_toList value =
-- Converting the stream to a list or pure stream in a strict monad
[ benchIOSink value "toList" S.toList
, benchIOSink value "toStream"
(Internal.toStream :: (SerialT IO Int -> IO (SerialT Identity Int)))
(S.toStream :: (SerialT IO Int -> IO (SerialT Identity Int)))
]
]
#endif
-------------------------------------------------------------------------------
-- Multi-stream folds
@ -673,14 +703,17 @@ benchmarks moduleName size =
, o_1_space_elimination_multi_stream_pure size
, o_1_space_elimination_multi_stream size
]
, bgroup (o_n_heap_prefix moduleName) $ concat
[ o_n_heap_elimination_foldl size
, o_n_heap_elimination_toList size
, o_n_heap_elimination_buffered size
]
, bgroup (o_n_space_prefix moduleName) $ concat
[ o_n_space_elimination_foldable size
, o_n_space_elimination_toList size
, o_n_space_elimination_foldr size
]
, bgroup (o_n_heap_prefix moduleName) $
o_n_heap_elimination_buffered size
#ifdef USE_PRELUDE
++ o_n_heap_elimination_foldl size
++ o_n_heap_elimination_toList size
#endif
, bgroup (o_n_space_prefix moduleName) $
o_n_space_elimination_foldable size
#ifdef USE_PRELUDE
++ o_n_space_elimination_toList size
#endif
++ o_n_space_elimination_foldr size
]

View File

@ -1,5 +1,5 @@
-- |
-- Module : Streamly.Benchmark.Prelude.Serial.Exceptions
-- Module : Stream.Exceptions
-- Copyright : (c) 2019 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -7,6 +7,7 @@
-- Portability : GHC
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
#ifdef __HADDOCK_VERSION__
@ -18,19 +19,25 @@
{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
#endif
module Serial.Exceptions (benchmarks) where
module Stream.Exceptions (benchmarks) where
import Control.Exception (SomeException, Exception, throwIO)
import Stream.Common (drain, enumerateFromTo)
import Streamly.Internal.Data.Stream.Serial (SerialT)
import System.IO (Handle, hClose, hPutChar)
import qualified Data.IORef as Ref
import qualified Data.Map.Strict as Map
import qualified Stream.Common as Common
import qualified Streamly.FileSystem.Handle as FH
import qualified Streamly.Internal.Data.Unfold as IUF
import qualified Streamly.Internal.FileSystem.Handle as IFH
import qualified Streamly.Internal.Data.Stream.IsStream as IP
import qualified Streamly.Prelude as S
#ifdef USE_PRELUDE
import qualified Streamly.Internal.Data.Stream.IsStream as Stream
#else
import qualified Streamly.Internal.Data.Stream as Stream
import qualified Streamly.Internal.Data.Unfold as Unfold
#endif
import Gauge hiding (env)
import Prelude hiding (last, length)
@ -47,6 +54,14 @@ import qualified Streamly.Internal.Data.Stream.StreamD as D
-- stream exceptions
-------------------------------------------------------------------------------
{-# INLINE replicateM #-}
replicateM :: Common.MonadAsync m => Int -> m a -> SerialT m a
#ifdef USE_PRELUDE
replicateM = Stream.replicateM
#else
replicateM = Stream.unfold . Unfold.replicateM
#endif
data BenchException
= BenchException1
| BenchException2
@ -56,37 +71,41 @@ instance Exception BenchException
retryNoneSimple :: Int -> Int -> IO ()
retryNoneSimple length from =
IP.drain
$ IP.retry (Map.singleton BenchException1 length) (const S.nil) source
drain
$ Stream.retry
(Map.singleton BenchException1 length)
(const Stream.nil)
source
where
source = S.enumerateFromTo from (from + length)
source = enumerateFromTo from (from + length)
retryNone :: Int -> Int -> IO ()
retryNone length from = do
ref <- Ref.newIORef (0 :: Int)
IP.drain
$ IP.retry (Map.singleton BenchException1 length) (const S.nil)
drain
$ Stream.retry (Map.singleton BenchException1 length) (const Stream.nil)
$ source ref
where
source ref =
IP.replicateM (from + length)
replicateM (from + length)
$ Ref.modifyIORef' ref (+ 1) >> Ref.readIORef ref
retryAll :: Int -> Int -> IO ()
retryAll length from = do
ref <- Ref.newIORef 0
IP.drain
$ IP.retry (Map.singleton BenchException1 (length + from)) (const S.nil)
drain
$ Stream.retry
(Map.singleton BenchException1 (length + from)) (const Stream.nil)
$ source ref
where
source ref =
IP.fromEffect
Stream.fromEffect
$ do
Ref.modifyIORef' ref (+ 1)
val <- Ref.readIORef ref
@ -96,13 +115,13 @@ retryAll length from = do
retryUnknown :: Int -> Int -> IO ()
retryUnknown length from = do
IP.drain
$ IP.retry (Map.singleton BenchException1 length) (const source)
$ throwIO BenchException2 `S.before` S.nil
drain
$ Stream.retry (Map.singleton BenchException1 length) (const source)
$ throwIO BenchException2 `Stream.before` Stream.nil
where
source = S.enumerateFromTo from (from + length)
source = enumerateFromTo from (from + length)
o_1_space_serial_exceptions :: Int -> [Benchmark]
@ -123,8 +142,8 @@ o_1_space_serial_exceptions length =
-- | Send the file contents to /dev/null with exception handling
readWriteOnExceptionStream :: Handle -> Handle -> IO ()
readWriteOnExceptionStream inh devNull =
let readEx = S.onException (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) $ readEx
let readEx = Stream.onException (hClose inh) (Stream.unfold FH.read inh)
in Stream.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readWriteOnExceptionStream
@ -133,9 +152,9 @@ inspect $ hasNoTypeClasses 'readWriteOnExceptionStream
-- | Send the file contents to /dev/null with exception handling
readWriteHandleExceptionStream :: Handle -> Handle -> IO ()
readWriteHandleExceptionStream inh devNull =
let handler (_e :: SomeException) = S.fromEffect (hClose inh >> return 10)
readEx = S.handle handler (S.unfold FH.read inh)
in S.fold (FH.write devNull) $ readEx
let handler (_e :: SomeException) = Stream.fromEffect (hClose inh >> return 10)
readEx = Stream.handle handler (Stream.unfold FH.read inh)
in Stream.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readWriteHandleExceptionStream
@ -144,8 +163,8 @@ inspect $ hasNoTypeClasses 'readWriteHandleExceptionStream
-- | Send the file contents to /dev/null with exception handling
readWriteFinally_Stream :: Handle -> Handle -> IO ()
readWriteFinally_Stream inh devNull =
let readEx = IP.finally_ (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
let readEx = Stream.finally_ (hClose inh) (Stream.unfold FH.read inh)
in Stream.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readWriteFinally_Stream
@ -153,15 +172,15 @@ inspect $ hasNoTypeClasses 'readWriteFinally_Stream
readWriteFinallyStream :: Handle -> Handle -> IO ()
readWriteFinallyStream inh devNull =
let readEx = S.finally (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
let readEx = Stream.finally (hClose inh) (Stream.unfold FH.read inh)
in Stream.fold (FH.write devNull) readEx
-- | Send the file contents to /dev/null with exception handling
fromToBytesBracket_Stream :: Handle -> Handle -> IO ()
fromToBytesBracket_Stream inh devNull =
let readEx = IP.bracket_ (return ()) (\_ -> hClose inh)
let readEx = Stream.bracket_ (return ()) (\_ -> hClose inh)
(\_ -> IFH.getBytes inh)
in IFH.putBytes devNull $ readEx
in IFH.putBytes devNull readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'fromToBytesBracket_Stream
@ -169,16 +188,16 @@ inspect $ hasNoTypeClasses 'fromToBytesBracket_Stream
fromToBytesBracketStream :: Handle -> Handle -> IO ()
fromToBytesBracketStream inh devNull =
let readEx = S.bracket (return ()) (\_ -> hClose inh)
let readEx = Stream.bracket (return ()) (\_ -> hClose inh)
(\_ -> IFH.getBytes inh)
in IFH.putBytes devNull $ readEx
in IFH.putBytes devNull readEx
readWriteBeforeAfterStream :: Handle -> Handle -> IO ()
readWriteBeforeAfterStream inh devNull =
let readEx =
IP.after (hClose inh)
$ IP.before (hPutChar devNull 'A') (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
Stream.after (hClose inh)
$ Stream.before (hPutChar devNull 'A') (Stream.unfold FH.read inh)
in Stream.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ 'readWriteBeforeAfterStream `hasNoType` ''D.Step
@ -186,8 +205,8 @@ inspect $ 'readWriteBeforeAfterStream `hasNoType` ''D.Step
readWriteAfterStream :: Handle -> Handle -> IO ()
readWriteAfterStream inh devNull =
let readEx = IP.after (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
let readEx = Stream.after (hClose inh) (Stream.unfold FH.read inh)
in Stream.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ 'readWriteAfterStream `hasNoType` ''D.Step
@ -195,8 +214,8 @@ inspect $ 'readWriteAfterStream `hasNoType` ''D.Step
readWriteAfter_Stream :: Handle -> Handle -> IO ()
readWriteAfter_Stream inh devNull =
let readEx = IP.after_ (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
let readEx = Stream.after_ (hClose inh) (Stream.unfold FH.read inh)
in Stream.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readWriteAfter_Stream
@ -206,25 +225,25 @@ inspect $ 'readWriteAfter_Stream `hasNoType` ''D.Step
o_1_space_copy_stream_exceptions :: BenchEnv -> [Benchmark]
o_1_space_copy_stream_exceptions env =
[ bgroup "exceptions"
[ mkBenchSmall "S.onException" env $ \inh _ ->
[ mkBenchSmall "Stream.onException" env $ \inh _ ->
readWriteOnExceptionStream inh (nullH env)
, mkBenchSmall "S.handle" env $ \inh _ ->
, mkBenchSmall "Stream.handle" env $ \inh _ ->
readWriteHandleExceptionStream inh (nullH env)
, mkBenchSmall "S.finally_" env $ \inh _ ->
, mkBenchSmall "Stream.finally_" env $ \inh _ ->
readWriteFinally_Stream inh (nullH env)
, mkBenchSmall "S.finally" env $ \inh _ ->
, mkBenchSmall "Stream.finally" env $ \inh _ ->
readWriteFinallyStream inh (nullH env)
, mkBenchSmall "S.after . S.before" env $ \inh _ ->
, mkBenchSmall "Stream.after . Stream.before" env $ \inh _ ->
readWriteBeforeAfterStream inh (nullH env)
, mkBenchSmall "S.after" env $ \inh _ ->
, mkBenchSmall "Stream.after" env $ \inh _ ->
readWriteAfterStream inh (nullH env)
, mkBenchSmall "S.after_" env $ \inh _ ->
, mkBenchSmall "Stream.after_" env $ \inh _ ->
readWriteAfter_Stream inh (nullH env)
]
, bgroup "exceptions/fromToBytes"
[ mkBenchSmall "S.bracket_" env $ \inh _ ->
[ mkBenchSmall "Stream.bracket_" env $ \inh _ ->
fromToBytesBracket_Stream inh (nullH env)
, mkBenchSmall "S.bracket" env $ \inh _ ->
, mkBenchSmall "Stream.bracket" env $ \inh _ ->
fromToBytesBracketStream inh (nullH env)
]
]
@ -277,11 +296,11 @@ o_1_space_copy_exceptions_readChunks env =
-- | Send the file contents to /dev/null with exception handling
toChunksBracket_ :: Handle -> Handle -> IO ()
toChunksBracket_ inh devNull =
let readEx = IP.bracket_
let readEx = Stream.bracket_
(return ())
(\_ -> hClose inh)
(\_ -> IFH.getChunks inh)
in S.fold (IFH.writeChunks devNull) $ readEx
in Stream.fold (IFH.writeChunks devNull) readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'toChunksBracket_
@ -289,23 +308,22 @@ inspect $ hasNoTypeClasses 'toChunksBracket_
toChunksBracket :: Handle -> Handle -> IO ()
toChunksBracket inh devNull =
let readEx = S.bracket
let readEx = Stream.bracket
(return ())
(\_ -> hClose inh)
(\_ -> IFH.getChunks inh)
in S.fold (IFH.writeChunks devNull) $ readEx
in Stream.fold (IFH.writeChunks devNull) readEx
o_1_space_copy_exceptions_toChunks :: BenchEnv -> [Benchmark]
o_1_space_copy_exceptions_toChunks env =
[ bgroup "exceptions/toChunks"
[ mkBench "S.bracket_" env $ \inH _ ->
[ mkBench "Stream.bracket_" env $ \inH _ ->
toChunksBracket_ inH (nullH env)
, mkBench "S.bracket" env $ \inH _ ->
, mkBench "Stream.bracket" env $ \inH _ ->
toChunksBracket inH (nullH env)
]
]
benchmarks :: String -> BenchEnv -> Int -> [Benchmark]
benchmarks moduleName env size =
[ bgroup (o_1_space_prefix moduleName) $ concat

View File

@ -1,5 +1,5 @@
-- |
-- Module : Serial.NestedStream
-- Module : Stream.Expand
-- Copyright : (c) 2018 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -18,9 +18,10 @@
{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
#endif
module Serial.NestedStream (benchmarks) where
module Stream.Expand (benchmarks) where
import Control.Monad.Trans.Class (lift)
import Streamly.Internal.Data.Stream.Serial (SerialT)
import qualified Control.Applicative as AP
@ -31,14 +32,23 @@ import Test.Inspection
import qualified Streamly.Internal.Data.Stream.StreamD as D
#endif
import qualified Streamly.Prelude as S
import qualified Streamly.Internal.Data.Stream.IsStream as Internal
import qualified Stream.Common as Common
#ifdef USE_PRELUDE
import qualified Streamly.Internal.Data.Stream.IsStream as S
import Streamly.Benchmark.Prelude hiding
(benchIOSrc, sourceUnfoldrM, apDiscardFst, apDiscardSnd, apLiftA2, toNullAp
, monadThen, toNullM, toNullM3, filterAllInM, filterAllOutM, filterSome
, breakAfterSome, toListM, toListSome)
#else
import Streamly.Benchmark.Prelude (benchIO)
import qualified Streamly.Internal.Data.Stream as S
#endif
import qualified Streamly.Internal.Data.Unfold as UF
import qualified Streamly.Internal.Data.Fold as Fold
import Gauge
import Streamly.Prelude (SerialT, fromSerial, serial)
import Stream.Common hiding (append2)
import Streamly.Benchmark.Common
import Streamly.Benchmark.Prelude
import Prelude hiding (concatMap)
-------------------------------------------------------------------------------
@ -56,13 +66,14 @@ iterateN g initial count = f count initial
-- Iterate a transformation over a singleton stream
{-# INLINE iterateSingleton #-}
iterateSingleton :: S.MonadAsync m
iterateSingleton :: Monad m
=> (Int -> SerialT m Int -> SerialT m Int)
-> Int
-> Int
-> SerialT m Int
iterateSingleton g count n = iterateN g (return n) count
{-
-- XXX need to check why this is slower than the explicit recursion above, even
-- if the above code is written in a foldr like head recursive way. We also
-- need to try this with foldlM' once #150 is fixed.
@ -70,12 +81,13 @@ iterateSingleton g count n = iterateN g (return n) count
-- foldrM and any related fusion issues.
{-# INLINE _iterateSingleton #-}
_iterateSingleton ::
S.MonadAsync m
Monad m
=> (Int -> SerialT m Int -> SerialT m Int)
-> Int
-> Int
-> SerialT m Int
_iterateSingleton g value n = S.foldrM g (return n) $ sourceIntFromTo value n
-}
-------------------------------------------------------------------------------
-- Multi-Stream
@ -88,34 +100,34 @@ _iterateSingleton g value n = S.foldrM g (return n) $ sourceIntFromTo value n
{-# INLINE serial2 #-}
serial2 :: Int -> Int -> IO ()
serial2 count n =
S.drain $
S.serial (sourceUnfoldrM count n) (sourceUnfoldrM count (n + 1))
drain $
Common.append (sourceUnfoldrM count n) (sourceUnfoldrM count (n + 1))
{-# INLINE serial4 #-}
serial4 :: Int -> Int -> IO ()
serial4 count n =
S.drain $
S.serial
(S.serial (sourceUnfoldrM count n) (sourceUnfoldrM count (n + 1)))
(S.serial
drain $
Common.append
(Common.append (sourceUnfoldrM count n) (sourceUnfoldrM count (n + 1)))
(Common.append
(sourceUnfoldrM count (n + 2))
(sourceUnfoldrM count (n + 3)))
{-# INLINE append2 #-}
append2 :: Int -> Int -> IO ()
append2 count n =
S.drain $
Internal.append (sourceUnfoldrM count n) (sourceUnfoldrM count (n + 1))
drain $
Common.append2 (sourceUnfoldrM count n) (sourceUnfoldrM count (n + 1))
{-# INLINE append4 #-}
append4 :: Int -> Int -> IO ()
append4 count n =
S.drain $
Internal.append
(Internal.append
drain $
Common.append2
(Common.append2
(sourceUnfoldrM count n)
(sourceUnfoldrM count (n + 1)))
(Internal.append
(Common.append2
(sourceUnfoldrM count (n + 2))
(sourceUnfoldrM count (n + 3)))
@ -139,22 +151,24 @@ o_1_space_joining value =
-- Concat Foldable containers
-------------------------------------------------------------------------------
#ifdef USE_PRELUDE
o_1_space_concatFoldable :: Int -> [Benchmark]
o_1_space_concatFoldable value =
[ bgroup "concat-foldable"
[ benchIOSrc fromSerial "foldMapWith (<>) (List)"
[ benchIOSrc "foldMapWith (<>) (List)"
(sourceFoldMapWith value)
, benchIOSrc fromSerial "foldMapWith (<>) (Stream)"
, benchIOSrc "foldMapWith (<>) (Stream)"
(sourceFoldMapWithStream value)
, benchIOSrc fromSerial "foldMapWithM (<>) (List)"
, benchIOSrc "foldMapWithM (<>) (List)"
(sourceFoldMapWithM value)
, benchIOSrc fromSerial "S.concatFoldableWith (<>) (List)"
, benchIOSrc "S.concatFoldableWith (<>) (List)"
(concatFoldableWith value)
, benchIOSrc fromSerial "S.concatForFoldableWith (<>) (List)"
, benchIOSrc "S.concatForFoldableWith (<>) (List)"
(concatForFoldableWith value)
, benchIOSrc fromSerial "foldMapM (List)" (sourceFoldMapM value)
, benchIOSrc "foldMapM (List)" (sourceFoldMapM value)
]
]
#endif
-------------------------------------------------------------------------------
-- Concat
@ -165,14 +179,14 @@ o_1_space_concatFoldable value =
{-# INLINE concatMap #-}
concatMap :: Int -> Int -> Int -> IO ()
concatMap outer inner n =
S.drain $ S.concatMap
drain $ S.concatMap
(\_ -> sourceUnfoldrM inner n)
(sourceUnfoldrM outer n)
{-# INLINE concatMapM #-}
concatMapM :: Int -> Int -> Int -> IO ()
concatMapM outer inner n =
S.drain $ S.concatMapM
drain $ S.concatMapM
(\_ -> return $ sourceUnfoldrM inner n)
(sourceUnfoldrM outer n)
@ -186,7 +200,7 @@ inspect $ 'concatMap `hasNoType` ''SPEC
{-# INLINE concatMapPure #-}
concatMapPure :: Int -> Int -> Int -> IO ()
concatMapPure outer inner n =
S.drain $ S.concatMap
drain $ S.concatMap
(\_ -> sourceUnfoldr inner n)
(sourceUnfoldr outer n)
@ -200,7 +214,7 @@ inspect $ 'concatMapPure `hasNoType` ''SPEC
{-# INLINE concatMapRepl #-}
concatMapRepl :: Int -> Int -> Int -> IO ()
concatMapRepl outer inner n =
S.drain $ S.concatMap (S.replicate inner) (sourceUnfoldrM outer n)
drain $ S.concatMap (Common.replicate inner) (sourceUnfoldrM outer n)
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'concatMapRepl
@ -211,7 +225,7 @@ inspect $ 'concatMapRepl `hasNoType` ''SPEC
{-# INLINE concatMapWithSerial #-}
concatMapWithSerial :: Int -> Int -> Int -> IO ()
concatMapWithSerial = concatStreamsWith S.serial
concatMapWithSerial = concatStreamsWith Common.append
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'concatMapWithSerial
@ -220,7 +234,7 @@ inspect $ 'concatMapWithSerial `hasNoType` ''SPEC
{-# INLINE concatMapWithAppend #-}
concatMapWithAppend :: Int -> Int -> Int -> IO ()
concatMapWithAppend = concatStreamsWith Internal.append
concatMapWithAppend = concatStreamsWith Common.append2
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'concatMapWithAppend
@ -231,11 +245,11 @@ inspect $ 'concatMapWithAppend `hasNoType` ''SPEC
{-# INLINE concatPairWithSerial #-}
concatPairWithSerial :: Int -> Int -> Int -> IO ()
concatPairWithSerial = concatPairsWith Internal.serial
concatPairWithSerial = concatPairsWith Common.append
{-# INLINE concatPairWithAppend #-}
concatPairWithAppend :: Int -> Int -> Int -> IO ()
concatPairWithAppend = concatPairsWith Internal.append
concatPairWithAppend = concatPairsWith Common.append2
-- unfoldMany
@ -244,7 +258,7 @@ concatPairWithAppend = concatPairsWith Internal.append
{-# INLINE unfoldManyRepl #-}
unfoldManyRepl :: Int -> Int -> Int -> IO ()
unfoldManyRepl outer inner n =
S.drain
drain
$ S.unfoldMany
(UF.lmap return (UF.replicateM inner))
(sourceUnfoldrM outer n)
@ -266,7 +280,7 @@ o_1_space_concat value = sqrtVal `seq`
(concatMapPure 1 value)
-- This is for comparison with foldMapWith
, benchIOSrc fromSerial "concatMapId (n of 1) (fromFoldable)"
, benchIOSrc "concatMapId (n of 1) (fromFoldable)"
(S.concatMap id . sourceConcatMapId value)
, benchIOSrc1 "concatMap (n of 1)"
@ -284,8 +298,8 @@ o_1_space_concat value = sqrtVal `seq`
(concatMapM 1 value)
-- This is for comparison with foldMapWith
, benchIOSrc fromSerial "concatMapWithId (n of 1) (fromFoldable)"
(S.concatMapWith serial id . sourceConcatMapId value)
, benchIOSrc "concatMapWithId (n of 1) (fromFoldable)"
(S.concatMapWith Common.append id . sourceConcatMapId value)
, benchIOSrc1 "concatMapWith (n of 1)"
(concatMapWithSerial value 1)
@ -343,23 +357,23 @@ o_n_space_concat value = sqrtVal `seq`
o_1_space_applicative :: Int -> [Benchmark]
o_1_space_applicative value =
[ bgroup "Applicative"
[ benchIO "(*>) (sqrt n x sqrt n)" $ apDiscardFst value fromSerial
, benchIO "(<*) (sqrt n x sqrt n)" $ apDiscardSnd value fromSerial
, benchIO "(<*>) (sqrt n x sqrt n)" $ toNullAp value fromSerial
, benchIO "liftA2 (sqrt n x sqrt n)" $ apLiftA2 value fromSerial
[ benchIO "(*>) (sqrt n x sqrt n)" $ apDiscardFst value
, benchIO "(<*) (sqrt n x sqrt n)" $ apDiscardSnd value
, benchIO "(<*>) (sqrt n x sqrt n)" $ toNullAp value
, benchIO "liftA2 (sqrt n x sqrt n)" $ apLiftA2 value
]
]
o_n_space_applicative :: Int -> [Benchmark]
o_n_space_applicative value =
[ bgroup "Applicative"
[ benchIOSrc fromSerial "(*>) (n times)" $
[ benchIOSrc "(*>) (n times)" $
iterateSingleton ((*>) . pure) value
, benchIOSrc fromSerial "(<*) (n times)" $
, benchIOSrc "(<*) (n times)" $
iterateSingleton (\x xs -> xs <* pure x) value
, benchIOSrc fromSerial "(<*>) (n times)" $
, benchIOSrc "(<*>) (n times)" $
iterateSingleton (\x xs -> pure (+ x) <*> xs) value
, benchIOSrc fromSerial "liftA2 (n times)" $
, benchIOSrc "liftA2 (n times)" $
iterateSingleton (AP.liftA2 (+) . pure) value
]
]
@ -371,18 +385,18 @@ o_n_space_applicative value =
o_1_space_monad :: Int -> [Benchmark]
o_1_space_monad value =
[ bgroup "Monad"
[ benchIO "(>>) (sqrt n x sqrt n)" $ monadThen value fromSerial
, benchIO "(>>=) (sqrt n x sqrt n)" $ toNullM value fromSerial
[ benchIO "(>>) (sqrt n x sqrt n)" $ monadThen value
, benchIO "(>>=) (sqrt n x sqrt n)" $ toNullM value
, benchIO "(>>=) (sqrt n x sqrt n) (filterAllOut)" $
filterAllOutM value fromSerial
filterAllOutM value
, benchIO "(>>=) (sqrt n x sqrt n) (filterAllIn)" $
filterAllInM value fromSerial
filterAllInM value
, benchIO "(>>=) (sqrt n x sqrt n) (filterSome)" $
filterSome value fromSerial
filterSome value
, benchIO "(>>=) (sqrt n x sqrt n) (breakAfterSome)" $
breakAfterSome value fromSerial
breakAfterSome value
, benchIO "(>>=) (cubert n x cubert n x cubert n)" $
toNullM3 value fromSerial
toNullM3 value
]
]
@ -400,16 +414,16 @@ sieve s = do
o_n_space_monad :: Int -> [Benchmark]
o_n_space_monad value =
[ bgroup "Monad"
[ benchIOSrc fromSerial "(>>) (n times)" $
[ benchIOSrc "(>>) (n times)" $
iterateSingleton ((>>) . pure) value
, benchIOSrc fromSerial "(>>=) (n times)" $
, benchIOSrc "(>>=) (n times)" $
iterateSingleton (\x xs -> xs >>= \y -> return (x + y)) value
, benchIO "(>>=) (sqrt n x sqrt n) (toList)" $
toListM value fromSerial
toListM value
, benchIO "(>>=) (sqrt n x sqrt n) (toListSome)" $
toListSome value fromSerial
toListSome value
, benchIO "naive prime sieve (n/4)"
(\n -> S.sum $ sieve $ S.enumerateFromTo 2 (value `div` 4 + n))
(\n -> S.fold Fold.sum $ sieve $ enumerateFromTo 2 (value `div` 4 + n))
]
]
@ -421,22 +435,22 @@ toKv :: Int -> (Int, Int)
toKv p = (p, p)
{-# INLINE joinWith #-}
joinWith :: (S.MonadAsync m) =>
joinWith :: Common.MonadAsync m =>
((Int -> Int -> Bool) -> SerialT m Int -> SerialT m Int -> SerialT m b)
-> Int
-> Int
-> m ()
joinWith j val i =
S.drain $ j (==) (sourceUnfoldrM val i) (sourceUnfoldrM val (val `div` 2))
drain $ j (==) (sourceUnfoldrM val i) (sourceUnfoldrM val (val `div` 2))
{-# INLINE joinMapWith #-}
joinMapWith :: (S.MonadAsync m) =>
joinMapWith :: Common.MonadAsync m =>
(SerialT m (Int, Int) -> SerialT m (Int, Int) -> SerialT m b)
-> Int
-> Int
-> m ()
joinMapWith j val i =
S.drain
drain
$ j
(fmap toKv (sourceUnfoldrM val i))
(fmap toKv (sourceUnfoldrM val (val `div` 2)))
@ -446,21 +460,21 @@ o_n_heap_buffering value =
[ bgroup "buffered"
[
benchIOSrc1 "joinInner (sqrtVal)"
$ joinWith Internal.joinInner sqrtVal
$ joinWith S.joinInner sqrtVal
, benchIOSrc1 "joinInnerMap"
$ joinMapWith Internal.joinInnerMap halfVal
$ joinMapWith S.joinInnerMap halfVal
, benchIOSrc1 "joinLeft (sqrtVal)"
$ joinWith Internal.joinLeft sqrtVal
$ joinWith S.joinLeft sqrtVal
, benchIOSrc1 "joinLeftMap "
$ joinMapWith Internal.joinLeftMap halfVal
$ joinMapWith S.joinLeftMap halfVal
, benchIOSrc1 "joinOuter (sqrtVal)"
$ joinWith Internal.joinOuter sqrtVal
$ joinWith S.joinOuter sqrtVal
, benchIOSrc1 "joinOuterMap"
$ joinMapWith Internal.joinOuterMap halfVal
$ joinMapWith S.joinOuterMap halfVal
, benchIOSrc1 "intersectBy (sqrtVal)"
$ joinWith Internal.intersectBy sqrtVal
$ joinWith S.intersectBy sqrtVal
, benchIOSrc1 "intersectBySorted"
$ joinMapWith (Internal.intersectBySorted compare) halfVal
$ joinMapWith (S.intersectBySorted compare) halfVal
]
]
@ -482,7 +496,9 @@ benchmarks moduleName size =
[
-- multi-stream
o_1_space_joining size
#ifdef USE_PRELUDE
, o_1_space_concatFoldable size
#endif
, o_1_space_concat size
, o_1_space_applicative size

View File

@ -1,5 +1,5 @@
-- |
-- Module : Serial.Generation
-- Module : Stream.Generate
-- Copyright : (c) 2018 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -9,19 +9,36 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
module Serial.Generation (benchmarks) where
module Stream.Generate (benchmarks) where
import Data.Functor.Identity (Identity)
import qualified Prelude
import qualified Stream.Common as Common
#ifdef USE_PRELUDE
import qualified GHC.Exts as GHC
import qualified Streamly.Prelude as S
import qualified Streamly.Prelude as S
import qualified Streamly.Internal.Data.Stream.IsStream as Stream
import qualified Prelude
#else
import qualified Streamly.Internal.Data.Stream as Stream
#endif
import Gauge
import Streamly.Prelude (SerialT, fromSerial, MonadAsync)
import Streamly.Benchmark.Common
import Streamly.Benchmark.Prelude
import Streamly.Internal.Data.Stream.Serial (SerialT)
#ifdef USE_PRELUDE
import Streamly.Prelude (MonadAsync)
import Stream.Common hiding (MonadAsync, replicate, enumerateFromTo)
import Streamly.Benchmark.Prelude hiding
(benchIOSrc, sourceUnfoldrM, apDiscardFst, apDiscardSnd, apLiftA2, toNullAp
, monadThen, toNullM, toNullM3, filterAllInM, filterAllOutM, filterSome
, breakAfterSome, toListM, toListSome)
#else
import Stream.Common
#endif
import System.IO.Unsafe (unsafeInterleaveIO)
import Prelude hiding (repeat, replicate, iterate)
-------------------------------------------------------------------------------
@ -32,6 +49,7 @@ import Prelude hiding (repeat, replicate, iterate)
-- fromList
-------------------------------------------------------------------------------
#ifdef USE_PRELUDE
{-# INLINE sourceIsList #-}
sourceIsList :: Int -> Int -> SerialT Identity Int
sourceIsList value n = GHC.fromList [n..n+value]
@ -39,6 +57,7 @@ sourceIsList value n = GHC.fromList [n..n+value]
{-# INLINE sourceIsString #-}
sourceIsString :: Int -> Int -> SerialT Identity Char
sourceIsString value n = GHC.fromString (Prelude.replicate (n + value) 'a')
#endif
{-# INLINE readInstance #-}
readInstance :: String -> SerialT Identity Int
@ -57,6 +76,7 @@ readInstanceList str =
[(x,"")] -> x
_ -> error "readInstance: no parse"
#ifdef USE_PRELUDE
{-# INLINE repeat #-}
repeat :: (Monad m, S.IsStream t) => Int -> Int -> t m Int
repeat count = S.take count . S.repeat
@ -114,41 +134,59 @@ fromIndices value n = S.take value $ S.fromIndices (+ n)
{-# INLINE fromIndicesM #-}
fromIndicesM :: (MonadAsync m, S.IsStream t) => Int -> Int -> t m Int
fromIndicesM value n = S.take value $ S.fromIndicesM (return <$> (+ n))
#endif
{-# INLINE mfixUnfold #-}
mfixUnfold :: Int -> Int -> SerialT IO (Int, Int)
mfixUnfold count start = Stream.mfix f
where
f action = do
let incr n act = fmap ((+n) . snd) $ unsafeInterleaveIO act
x <- Common.fromListM [incr 1 action, incr 2 action]
y <- Common.sourceUnfoldr count start
return (x, y)
o_1_space_generation :: Int -> [Benchmark]
o_1_space_generation value =
[ bgroup "generation"
[ benchIOSrc fromSerial "unfoldr" (sourceUnfoldr value)
, benchIOSrc fromSerial "unfoldrM" (sourceUnfoldrM value)
, benchIOSrc fromSerial "repeat" (repeat value)
, benchIOSrc fromSerial "repeatM" (repeatM value)
, benchIOSrc fromSerial "replicate" (replicate value)
, benchIOSrc fromSerial "replicateM" (replicateM value)
, benchIOSrc fromSerial "iterate" (iterate value)
, benchIOSrc fromSerial "iterateM" (iterateM value)
, benchIOSrc fromSerial "fromIndices" (fromIndices value)
, benchIOSrc fromSerial "fromIndicesM" (fromIndicesM value)
, benchIOSrc fromSerial "intFromTo" (sourceIntFromTo value)
, benchIOSrc fromSerial "intFromThenTo" (sourceIntFromThenTo value)
, benchIOSrc fromSerial "integerFromStep" (sourceIntegerFromStep value)
, benchIOSrc fromSerial "fracFromThenTo" (sourceFracFromThenTo value)
, benchIOSrc fromSerial "fracFromTo" (sourceFracFromTo value)
, benchIOSrc fromSerial "fromList" (sourceFromList value)
[ benchIOSrc "unfoldr" (sourceUnfoldr value)
, benchIOSrc "unfoldrM" (sourceUnfoldrM value)
#ifdef USE_PRELUDE
, benchIOSrc "repeat" (repeat value)
, benchIOSrc "repeatM" (repeatM value)
, benchIOSrc "replicate" (replicate value)
, benchIOSrc "replicateM" (replicateM value)
, benchIOSrc "iterate" (iterate value)
, benchIOSrc "iterateM" (iterateM value)
, benchIOSrc "fromIndices" (fromIndices value)
, benchIOSrc "fromIndicesM" (fromIndicesM value)
, benchIOSrc "intFromTo" (sourceIntFromTo value)
, benchIOSrc "intFromThenTo" (sourceIntFromThenTo value)
, benchIOSrc "integerFromStep" (sourceIntegerFromStep value)
, benchIOSrc "fracFromThenTo" (sourceFracFromThenTo value)
, benchIOSrc "fracFromTo" (sourceFracFromTo value)
, benchIOSrc "fromList" (sourceFromList value)
, benchPureSrc "IsList.fromList" (sourceIsList value)
, benchPureSrc "IsString.fromString" (sourceIsString value)
, benchIOSrc fromSerial "fromListM" (sourceFromListM value)
, benchIOSrc fromSerial "enumerateFrom" (enumerateFrom value)
, benchIOSrc fromSerial "enumerateFromTo" (enumerateFromTo value)
, benchIOSrc fromSerial "enumerateFromThen" (enumerateFromThen value)
, benchIOSrc fromSerial "enumerateFromThenTo" (enumerateFromThenTo value)
, benchIOSrc fromSerial "enumerate" (enumerate value)
, benchIOSrc fromSerial "enumerateTo" (enumerateTo value)
, benchIOSrc "fromListM" (sourceFromListM value)
, benchIOSrc "enumerateFrom" (enumerateFrom value)
, benchIOSrc "enumerateFromTo" (enumerateFromTo value)
, benchIOSrc "enumerateFromThen" (enumerateFromThen value)
, benchIOSrc "enumerateFromThenTo" (enumerateFromThenTo value)
, benchIOSrc "enumerate" (enumerate value)
, benchIOSrc "enumerateTo" (enumerateTo value)
#endif
-- These essentially test cons and consM
, benchIOSrc fromSerial "fromFoldable" (sourceFromFoldable value)
, benchIOSrc fromSerial "fromFoldableM" (sourceFromFoldableM value)
, benchIOSrc "fromFoldable" (sourceFromFoldable value)
, benchIOSrc "fromFoldableM" (sourceFromFoldableM value)
, benchIOSrc fromSerial "absTimes" $ absTimes value
#ifdef USE_PRELUDE
, benchIOSrc "absTimes" $ absTimes value
#endif
, Common.benchIOSrc "mfix_10" (mfixUnfold 10)
, Common.benchIOSrc "mfix_100" (mfixUnfold 100)
, Common.benchIOSrc "mfix_1000" (mfixUnfold 1000)
]
]

View File

@ -1,5 +1,5 @@
-- |
-- Module : Serial.Lift
-- Module : Stream.Lift
-- Copyright : (c) 2018 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -9,19 +9,30 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
module Serial.Lift (benchmarks) where
module Stream.Lift (benchmarks) where
import Control.Monad.State.Strict (StateT, get, put, MonadState)
import qualified Control.Monad.State.Strict as State
import Control.DeepSeq (NFData(..))
import Control.Monad.Trans.Class (lift)
import qualified Streamly.Prelude as S
import qualified Streamly.Internal.Data.Stream.IsStream as Internal
import Control.Monad.State.Strict (StateT, get, put, MonadState)
import Data.Functor.Identity (Identity)
import Stream.Common (sourceUnfoldr, sourceUnfoldrM, benchIOSrc, drain)
import System.Random (randomRIO)
#ifdef USE_PRELUDE
import Streamly.Benchmark.Prelude hiding
(sourceUnfoldr, sourceUnfoldrM, benchIOSrc)
import qualified Streamly.Internal.Data.Stream.IsStream as Stream
#else
import Streamly.Benchmark.Prelude (benchIO)
import qualified Streamly.Internal.Data.Stream as Stream
#endif
import qualified Streamly.Internal.Data.Fold as Fold
import qualified Stream.Common as Common
import qualified Control.Monad.State.Strict as State
import Gauge
import Streamly.Prelude (SerialT, fromSerial)
import Streamly.Internal.Data.Stream.Serial (SerialT)
import Streamly.Benchmark.Common
import Streamly.Benchmark.Prelude
import Prelude hiding (reverse, tail)
-------------------------------------------------------------------------------
@ -29,9 +40,9 @@ import Prelude hiding (reverse, tail)
-------------------------------------------------------------------------------
{-# INLINE sourceUnfoldrState #-}
sourceUnfoldrState :: (S.IsStream t, S.MonadAsync m)
=> Int -> Int -> t (StateT Int m) Int
sourceUnfoldrState value n = S.unfoldrM step n
sourceUnfoldrState :: Common.MonadAsync m =>
Int -> Int -> SerialT (StateT Int m) Int
sourceUnfoldrState value n = Common.unfoldrM step n
where
step cnt =
if cnt > n + value
@ -42,27 +53,36 @@ sourceUnfoldrState value n = S.unfoldrM step n
return (Just (s, cnt + 1))
{-# INLINE evalStateT #-}
evalStateT :: S.MonadAsync m => Int -> Int -> SerialT m Int
evalStateT :: Common.MonadAsync m => Int -> Int -> SerialT m Int
evalStateT value n =
Internal.evalStateT (return 0) (sourceUnfoldrState value n)
Stream.evalStateT (return 0) (sourceUnfoldrState value n)
{-# INLINE withState #-}
withState :: S.MonadAsync m => Int -> Int -> SerialT m Int
withState :: Common.MonadAsync m => Int -> Int -> SerialT m Int
withState value n =
Internal.evalStateT
(return (0 :: Int)) (Internal.liftInner (sourceUnfoldrM value n))
Stream.evalStateT
(return (0 :: Int)) (Stream.liftInner (sourceUnfoldrM value n))
{-# INLINE benchHoistSink #-}
benchHoistSink
:: (NFData b)
=> Int -> String -> (SerialT Identity Int -> IO b) -> Benchmark
benchHoistSink value name f =
bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldr value
o_1_space_hoisting :: Int -> [Benchmark]
o_1_space_hoisting value =
[ bgroup "hoisting"
[ benchIOSrc fromSerial "evalState" (evalStateT value)
, benchIOSrc fromSerial "withState" (withState value)
[ benchIOSrc "evalState" (evalStateT value)
, benchIOSrc "withState" (withState value)
, benchHoistSink value "generally"
((\xs -> Stream.fold Fold.length xs :: IO Int) . Stream.generally)
]
]
{-# INLINE iterateStateIO #-}
iterateStateIO ::
(S.MonadAsync m)
Monad m
=> Int
-> StateT Int m Int
iterateStateIO n = do
@ -86,7 +106,7 @@ iterateStateT n = do
{-# INLINE iterateState #-}
{-# SPECIALIZE iterateState :: Int -> SerialT (StateT Int IO) Int #-}
iterateState ::
(S.MonadAsync m, MonadState Int m)
MonadState Int m
=> Int
-> SerialT m Int
iterateState n = do
@ -103,9 +123,9 @@ o_n_heap_transformer value =
[ benchIO "StateT Int IO (n times) (baseline)" $ \n ->
State.evalStateT (iterateStateIO n) value
, benchIO "SerialT (StateT Int IO) (n times)" $ \n ->
State.evalStateT (S.drain (iterateStateT n)) value
State.evalStateT (drain (iterateStateT n)) value
, benchIO "MonadState Int m => SerialT m Int" $ \n ->
State.evalStateT (S.drain (iterateState n)) value
State.evalStateT (drain (iterateState n)) value
]
]

View File

@ -1,5 +1,5 @@
-- |
-- Module : Serial.NestedFold
-- Module : Stream.Reduce
-- Copyright : (c) 2018 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -11,26 +11,37 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE RankNTypes #-}
module Serial.NestedFold (benchmarks) where
module Stream.Reduce (benchmarks) where
import Control.DeepSeq (NFData(..))
import Control.Monad (when)
import Control.Monad.IO.Class (MonadIO(..))
import Data.Monoid (Sum(..))
import Data.Proxy (Proxy(..))
import Data.HashMap.Strict (HashMap)
import GHC.Generics (Generic)
import Streamly.Internal.Data.IsMap.HashMap ()
import Streamly.Internal.Data.Stream.Serial (SerialT)
import qualified Streamly.Internal.Data.Refold.Type as Refold
import qualified Streamly.Internal.Data.Fold as FL
import qualified Streamly.Internal.Data.Stream.IsStream as Internal
import qualified Streamly.Prelude as S
import qualified Stream.Common as Common
#ifdef USE_PRELUDE
import Control.Monad (when)
import Data.Proxy (Proxy(..))
import Data.HashMap.Strict (HashMap)
import qualified Streamly.Internal.Data.Stream.IsStream as S
import Streamly.Prelude (fromSerial)
import Streamly.Benchmark.Prelude hiding
( benchIOSrc, sourceUnfoldrM, apDiscardFst, apDiscardSnd, apLiftA2
, toNullAp, monadThen, toNullM, toNullM3, filterAllInM, filterAllOutM
, filterSome, breakAfterSome, toListM, toListSome, transformMapM
, transformComposeMapM, transformTeeMapM, transformZipMapM)
#else
import Streamly.Benchmark.Prelude (benchIO)
import qualified Streamly.Internal.Data.Stream as S
#endif
import Gauge
import Streamly.Prelude (SerialT, fromSerial)
import Streamly.Benchmark.Common
import Streamly.Benchmark.Prelude
import Stream.Common
import Prelude hiding (reverse, tail)
-------------------------------------------------------------------------------
@ -48,13 +59,14 @@ iterateN g initial count = f count initial
-- Iterate a transformation over a singleton stream
{-# INLINE iterateSingleton #-}
iterateSingleton :: S.MonadAsync m
iterateSingleton :: Monad m
=> (Int -> SerialT m Int -> SerialT m Int)
-> Int
-> Int
-> SerialT m Int
iterateSingleton g count n = iterateN g (return n) count
{-
-- XXX need to check why this is slower than the explicit recursion above, even
-- if the above code is written in a foldr like head recursive way. We also
-- need to try this with foldlM' once #150 is fixed.
@ -62,17 +74,18 @@ iterateSingleton g count n = iterateN g (return n) count
-- foldrM and any related fusion issues.
{-# INLINE _iterateSingleton #-}
_iterateSingleton ::
S.MonadAsync m
Monad m
=> (Int -> SerialT m Int -> SerialT m Int)
-> Int
-> Int
-> SerialT m Int
_iterateSingleton g value n = S.foldrM g (return n) $ sourceIntFromTo value n
-}
-- Apply transformation g count times on a stream of length len
{-# INLINE iterateSource #-}
iterateSource ::
S.MonadAsync m
MonadAsync m
=> (SerialT m Int -> SerialT m Int)
-> Int
-> Int
@ -94,9 +107,9 @@ o_n_space_functor value =
[ bgroup "Functor"
[ benchIO "(+) (n times) (baseline)" $ \i0 ->
iterateN (\i acc -> acc >>= \n -> return $ i + n) (return i0) value
, benchIOSrc fromSerial "(<$) (n times)" $
, benchIOSrc "(<$) (n times)" $
iterateSingleton (<$) value
, benchIOSrc fromSerial "fmap (n times)" $
, benchIOSrc "fmap (n times)" $
iterateSingleton (fmap . (+)) value
{-
, benchIOSrc fromSerial "_(<$) (n times)" $
@ -111,74 +124,92 @@ o_n_space_functor value =
-- Grouping transformations
-------------------------------------------------------------------------------
#ifdef USE_PRELUDE
{-# INLINE groups #-}
groups :: MonadIO m => SerialT m Int -> m ()
groups = S.drain . S.groups FL.drain
groups = Common.drain . S.groups FL.drain
-- XXX Change this test when the order of comparison is later changed
{-# INLINE groupsByGT #-}
groupsByGT :: MonadIO m => SerialT m Int -> m ()
groupsByGT = S.drain . S.groupsBy (>) FL.drain
groupsByGT = Common.drain . S.groupsBy (>) FL.drain
{-# INLINE groupsByEq #-}
groupsByEq :: MonadIO m => SerialT m Int -> m ()
groupsByEq = S.drain . S.groupsBy (==) FL.drain
groupsByEq = Common.drain . S.groupsBy (==) FL.drain
-- XXX Change this test when the order of comparison is later changed
{-# INLINE groupsByRollingLT #-}
groupsByRollingLT :: MonadIO m => SerialT m Int -> m ()
groupsByRollingLT =
S.drain . S.groupsByRolling (<) FL.drain
Common.drain . S.groupsByRolling (<) FL.drain
{-# INLINE groupsByRollingEq #-}
groupsByRollingEq :: MonadIO m => SerialT m Int -> m ()
groupsByRollingEq =
S.drain . S.groupsByRolling (==) FL.drain
Common.drain . S.groupsByRolling (==) FL.drain
#endif
{-# INLINE foldMany #-}
foldMany :: Monad m => SerialT m Int -> m ()
foldMany =
S.drain
. S.map getSum
. Internal.foldMany (FL.take 2 FL.mconcat)
. S.map Sum
Common.drain
. fmap getSum
. S.foldMany (FL.take 2 FL.mconcat)
. fmap Sum
{-# INLINE foldManyPost #-}
foldManyPost :: Monad m => SerialT m Int -> m ()
foldManyPost =
Common.drain
. fmap getSum
. S.foldManyPost (FL.take 2 FL.mconcat)
. fmap Sum
{-# INLINE refoldMany #-}
refoldMany :: Monad m => SerialT m Int -> m ()
refoldMany =
S.drain
. S.map getSum
. Internal.refoldMany (Refold.take 2 Refold.sconcat) (return mempty)
. S.map Sum
Common.drain
. fmap getSum
. S.refoldMany (Refold.take 2 Refold.sconcat) (return mempty)
. fmap Sum
{-# INLINE foldIterateM #-}
foldIterateM :: Monad m => SerialT m Int -> m ()
foldIterateM =
S.drain
. S.map getSum
. Internal.foldIterateM
Common.drain
. fmap getSum
. S.foldIterateM
(return . FL.take 2 . FL.sconcat) (return (Sum 0))
. S.map Sum
. fmap Sum
{-# INLINE refoldIterateM #-}
refoldIterateM :: Monad m => SerialT m Int -> m ()
refoldIterateM =
S.drain
. S.map getSum
. Internal.refoldIterateM
Common.drain
. fmap getSum
. S.refoldIterateM
(Refold.take 2 Refold.sconcat) (return (Sum 0))
. S.map Sum
. fmap Sum
o_1_space_grouping :: Int -> [Benchmark]
o_1_space_grouping value =
-- Buffering operations using heap proportional to group/window sizes.
[ bgroup "grouping"
[ benchIOSink value "groups" groups
[
#ifdef USE_PRELUDE
benchIOSink value "groups" groups
, benchIOSink value "groupsByGT" groupsByGT
, benchIOSink value "groupsByEq" groupsByEq
, benchIOSink value "groupsByRollingLT" groupsByRollingLT
, benchIOSink value "groupsByRollingEq" groupsByRollingEq
, benchIOSink value "foldMany" foldMany
,
#endif
-- XXX parseMany/parseIterate benchmarks are in the Parser/ParserD
-- modules we can bring those here. arraysOf benchmarks are in
-- Parser/ParserD/Array.Stream/FileSystem.Handle.
benchIOSink value "foldMany" foldMany
, benchIOSink value "foldManyPost" foldManyPost
, benchIOSink value "refoldMany" refoldMany
, benchIOSink value "foldIterateM" foldIterateM
, benchIOSink value "refoldIterateM" refoldIterateM
@ -195,7 +226,7 @@ reverse n = composeN n S.reverse
{-# INLINE reverse' #-}
reverse' :: MonadIO m => Int -> SerialT m Int -> m ()
reverse' n = composeN n Internal.reverse'
reverse' n = composeN n S.reverse'
o_n_heap_buffering :: Int -> [Benchmark]
o_n_heap_buffering value =
@ -205,7 +236,9 @@ o_n_heap_buffering value =
benchIOSink value "reverse" (reverse 1)
, benchIOSink value "reverse'" (reverse' 1)
#ifdef USE_PRELUDE
, benchIOSink value "mkAsync" (mkAsync fromSerial)
#endif
]
]
@ -213,25 +246,26 @@ o_n_heap_buffering value =
-- Grouping/Splitting
-------------------------------------------------------------------------------
#ifdef USE_PRELUDE
{-# INLINE classifySessionsOf #-}
classifySessionsOf :: S.MonadAsync m => (Int -> Int) -> SerialT m Int -> m ()
classifySessionsOf :: MonadAsync m => (Int -> Int) -> SerialT m Int -> m ()
classifySessionsOf getKey =
S.drain
. Internal.classifySessionsOf
Common.drain
. S.classifySessionsOf
(const (return False)) 3 (FL.take 10 FL.sum)
. Internal.timestamped
. S.map (\x -> (getKey x, x))
. S.timestamped
. fmap (\x -> (getKey x, x))
{-# INLINE classifySessionsOfHash #-}
classifySessionsOfHash :: S.MonadAsync m =>
classifySessionsOfHash :: MonadAsync m =>
(Int -> Int) -> SerialT m Int -> m ()
classifySessionsOfHash getKey =
S.drain
. Internal.classifySessionsByGeneric
Common.drain
. S.classifySessionsByGeneric
(Proxy :: Proxy (HashMap k))
1 False (const (return False)) 3 (FL.take 10 FL.sum)
. Internal.timestamped
. S.map (\x -> (getKey x, x))
. S.timestamped
. fmap (\x -> (getKey x, x))
o_n_space_grouping :: Int -> [Benchmark]
o_n_space_grouping value =
@ -251,6 +285,7 @@ o_n_space_grouping value =
where
getKey n = (`mod` n)
#endif
-------------------------------------------------------------------------------
-- Mixed Transformation
@ -258,15 +293,15 @@ o_n_space_grouping value =
{-# INLINE scanMap #-}
scanMap :: MonadIO m => Int -> SerialT m Int -> m ()
scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
scanMap n = composeN n $ fmap (subtract 1) . Common.scanl' (+) 0
{-# INLINE dropMap #-}
dropMap :: MonadIO m => Int -> SerialT m Int -> m ()
dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
dropMap n = composeN n $ fmap (subtract 1) . S.drop 1
{-# INLINE dropScan #-}
dropScan :: MonadIO m => Int -> SerialT m Int -> m ()
dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
dropScan n = composeN n $ Common.scanl' (+) 0 . S.drop 1
{-# INLINE takeDrop #-}
takeDrop :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
@ -274,11 +309,11 @@ takeDrop value n = composeN n $ S.drop 1 . S.take (value + 1)
{-# INLINE takeScan #-}
takeScan :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
takeScan value n = composeN n $ S.scanl' (+) 0 . S.take (value + 1)
takeScan value n = composeN n $ Common.scanl' (+) 0 . S.take (value + 1)
{-# INLINE takeMap #-}
takeMap :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
takeMap value n = composeN n $ S.map (subtract 1) . S.take (value + 1)
takeMap value n = composeN n $ fmap (subtract 1) . S.take (value + 1)
{-# INLINE filterDrop #-}
filterDrop :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
@ -290,15 +325,17 @@ filterTake value n = composeN n $ S.take (value + 1) . S.filter (<= (value + 1))
{-# INLINE filterScan #-}
filterScan :: MonadIO m => Int -> SerialT m Int -> m ()
filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
filterScan n = composeN n $ Common.scanl' (+) 0 . S.filter (<= maxBound)
#ifdef USE_PRELUDE
{-# INLINE filterScanl1 #-}
filterScanl1 :: MonadIO m => Int -> SerialT m Int -> m ()
filterScanl1 n = composeN n $ S.scanl1' (+) . S.filter (<= maxBound)
#endif
{-# INLINE filterMap #-}
filterMap :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
filterMap value n = composeN n $ S.map (subtract 1) . S.filter (<= (value + 1))
filterMap value n = composeN n $ fmap (subtract 1) . S.filter (<= (value + 1))
-------------------------------------------------------------------------------
-- Scan and fold
@ -310,17 +347,17 @@ data Pair a b =
{-# INLINE sumProductFold #-}
sumProductFold :: Monad m => SerialT m Int -> m (Int, Int)
sumProductFold = S.foldl' (\(s, p) x -> (s + x, p * x)) (0, 1)
sumProductFold = Common.foldl' (\(s, p) x -> (s + x, p * x)) (0, 1)
{-# INLINE sumProductScan #-}
sumProductScan :: Monad m => SerialT m Int -> m (Pair Int Int)
sumProductScan =
S.foldl' (\(Pair _ p) (s0, x) -> Pair s0 (p * x)) (Pair 0 1) .
S.scanl' (\(s, _) x -> (s + x, x)) (0, 0)
Common.foldl' (\(Pair _ p) (s0, x) -> Pair s0 (p * x)) (Pair 0 1) .
Common.scanl' (\(s, _) x -> (s + x, x)) (0, 0)
{-# INLINE foldl'ReduceMap #-}
foldl'ReduceMap :: Monad m => SerialT m Int -> m Int
foldl'ReduceMap = fmap (+ 1) . S.foldl' (+) 0
foldl'ReduceMap = fmap (+ 1) . Common.foldl' (+) 0
o_1_space_transformations_mixed :: Int -> [Benchmark]
o_1_space_transformations_mixed value =
@ -347,7 +384,9 @@ o_1_space_transformations_mixedX4 value =
, benchIOSink value "filter-drop" (filterDrop value 4)
, benchIOSink value "filter-take" (filterTake value 4)
, benchIOSink value "filter-scan" (filterScan 4)
#ifdef USE_PRELUDE
, benchIOSink value "filter-scanl1" (filterScanl1 4)
#endif
, benchIOSink value "filter-map" (filterMap value 4)
]
]
@ -358,40 +397,43 @@ o_1_space_transformations_mixedX4 value =
-- this is quadratic
{-# INLINE iterateScan #-}
iterateScan :: S.MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateScan = iterateSource (S.scanl' (+) 0)
iterateScan :: MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateScan = iterateSource (Common.scanl' (+) 0)
#ifdef USE_PRELUDE
-- this is quadratic
{-# INLINE iterateScanl1 #-}
iterateScanl1 :: S.MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateScanl1 :: MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateScanl1 = iterateSource (S.scanl1' (+))
#endif
{-# INLINE iterateMapM #-}
iterateMapM :: S.MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateMapM :: MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateMapM = iterateSource (S.mapM return)
{-# INLINE iterateFilterEven #-}
iterateFilterEven :: S.MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateFilterEven :: MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateFilterEven = iterateSource (S.filter even)
{-# INLINE iterateTakeAll #-}
iterateTakeAll :: S.MonadAsync m => Int -> Int -> Int -> Int -> SerialT m Int
iterateTakeAll :: MonadAsync m => Int -> Int -> Int -> Int -> SerialT m Int
iterateTakeAll value = iterateSource (S.take (value + 1))
{-# INLINE iterateDropOne #-}
iterateDropOne :: S.MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateDropOne :: MonadAsync m => Int -> Int -> Int -> SerialT m Int
iterateDropOne = iterateSource (S.drop 1)
{-# INLINE iterateDropWhileFalse #-}
iterateDropWhileFalse :: S.MonadAsync m
iterateDropWhileFalse :: MonadAsync m
=> Int -> Int -> Int -> Int -> SerialT m Int
iterateDropWhileFalse value = iterateSource (S.dropWhile (> (value + 1)))
{-# INLINE iterateDropWhileTrue #-}
iterateDropWhileTrue :: S.MonadAsync m
iterateDropWhileTrue :: MonadAsync m
=> Int -> Int -> Int -> Int -> SerialT m Int
iterateDropWhileTrue value = iterateSource (S.dropWhile (<= (value + 1)))
#ifdef USE_PRELUDE
{-# INLINE tail #-}
tail :: Monad m => SerialT m a -> m ()
tail s = S.tail s >>= mapM_ tail
@ -403,26 +445,31 @@ nullHeadTail s = do
when (not r) $ do
_ <- S.head s
S.tail s >>= mapM_ nullHeadTail
#endif
-- Head recursive operations.
o_n_stack_iterated :: Int -> [Benchmark]
o_n_stack_iterated value = by10 `seq` by100 `seq`
[ bgroup "iterated"
[ benchIOSrc fromSerial "mapM (n/10 x 10)" $ iterateMapM by10 10
, benchIOSrc fromSerial "scanl' (quadratic) (n/100 x 100)" $
[ benchIOSrc "mapM (n/10 x 10)" $ iterateMapM by10 10
, benchIOSrc "scanl' (quadratic) (n/100 x 100)" $
iterateScan by100 100
, benchIOSrc fromSerial "scanl1' (n/10 x 10)" $ iterateScanl1 by10 10
, benchIOSrc fromSerial "filterEven (n/10 x 10)" $
#ifdef USE_PRELUDE
, benchIOSrc "scanl1' (n/10 x 10)" $ iterateScanl1 by10 10
#endif
, benchIOSrc "filterEven (n/10 x 10)" $
iterateFilterEven by10 10
, benchIOSrc fromSerial "takeAll (n/10 x 10)" $
, benchIOSrc "takeAll (n/10 x 10)" $
iterateTakeAll value by10 10
, benchIOSrc fromSerial "dropOne (n/10 x 10)" $ iterateDropOne by10 10
, benchIOSrc fromSerial "dropWhileFalse (n/10 x 10)" $
, benchIOSrc "dropOne (n/10 x 10)" $ iterateDropOne by10 10
, benchIOSrc "dropWhileFalse (n/10 x 10)" $
iterateDropWhileFalse value by10 10
, benchIOSrc fromSerial "dropWhileTrue (n/10 x 10)" $
, benchIOSrc "dropWhileTrue (n/10 x 10)" $
iterateDropWhileTrue value by10 10
#ifdef USE_PRELUDE
, benchIOSink value "tail" tail
, benchIOSink value "nullHeadTail" nullHeadTail
#endif
]
]
@ -438,12 +485,12 @@ o_n_stack_iterated value = by10 `seq` by100 `seq`
o_1_space_pipes :: Int -> [Benchmark]
o_1_space_pipes value =
[ bgroup "pipes"
[ benchIOSink value "mapM" (transformMapM fromSerial 1)
, benchIOSink value "compose" (transformComposeMapM fromSerial 1)
, benchIOSink value "tee" (transformTeeMapM fromSerial 1)
[ benchIOSink value "mapM" (transformMapM 1)
, benchIOSink value "compose" (transformComposeMapM 1)
, benchIOSink value "tee" (transformTeeMapM 1)
#ifdef DEVBUILD
-- XXX this take 1 GB memory to compile
, benchIOSink value "zip" (transformZipMapM fromSerial 1)
, benchIOSink value "zip" (transformZipMapM 1)
#endif
]
]
@ -451,12 +498,12 @@ o_1_space_pipes value =
o_1_space_pipesX4 :: Int -> [Benchmark]
o_1_space_pipesX4 value =
[ bgroup "pipesX4"
[ benchIOSink value "mapM" (transformMapM fromSerial 4)
, benchIOSink value "compose" (transformComposeMapM fromSerial 4)
, benchIOSink value "tee" (transformTeeMapM fromSerial 4)
[ benchIOSink value "mapM" (transformMapM 4)
, benchIOSink value "compose" (transformComposeMapM 4)
, benchIOSink value "tee" (transformTeeMapM 4)
#ifdef DEVBUILD
-- XXX this take 1 GB memory to compile
, benchIOSink value "zip" (transformZipMapM fromSerial 4)
, benchIOSink value "zip" (transformZipMapM 4)
#endif
]
]
@ -481,8 +528,12 @@ benchmarks moduleName size =
]
, bgroup (o_n_stack_prefix moduleName) (o_n_stack_iterated size)
, bgroup (o_n_heap_prefix moduleName) $ Prelude.concat
[ o_n_space_grouping size
, o_n_space_functor size
[
#ifdef USE_PRELUDE
o_n_space_grouping size
,
#endif
o_n_space_functor size
, o_n_heap_buffering size
]
]

View File

@ -1,5 +1,5 @@
-- |
-- Module : Streamly.Benchmark.Prelude.Serial.Split
-- Module : Stream.Split
-- Copyright : (c) 2019 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -18,7 +18,7 @@
{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
#endif
module Serial.Split (benchmarks) where
module Stream.Split (benchmarks) where
import Data.Char (ord)
import Data.Word (Word8)

View File

@ -1,5 +1,5 @@
-- |
-- Module : Serial.Transformation
-- Module : Stream.Transform
-- Copyright : (c) 2018 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
@ -18,30 +18,37 @@
{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
#endif
module Serial.Transformation (benchmarks) where
module Stream.Transform (benchmarks) where
import Control.DeepSeq (NFData(..))
import Control.Monad.IO.Class (MonadIO(..))
import Data.Functor.Identity (Identity)
import System.Random (randomRIO)
#ifdef INSPECTION
import Test.Inspection
import qualified Streamly.Internal.Data.Fold as FL
import qualified Prelude
import qualified Stream.Common as Common
import qualified Streamly.Internal.Data.Unfold as Unfold
#ifdef USE_PRELUDE
import Streamly.Benchmark.Prelude hiding
( benchIOSrc, sourceUnfoldrM, apDiscardFst, apDiscardSnd, apLiftA2, toNullAp
, monadThen, toNullM, toNullM3, filterAllInM, filterAllOutM, filterSome
, breakAfterSome, toListM, toListSome, transformMapM, transformComposeMapM
, transformTeeMapM, transformZipMapM, mapN, mapM)
import qualified Streamly.Internal.Data.Stream.IsStream as Stream
import Streamly.Internal.Data.Time.Units
#else
import Streamly.Benchmark.Prelude (benchIO)
import qualified Streamly.Internal.Data.Stream as Stream
#endif
import qualified Streamly.Prelude as S
import qualified Streamly.Internal.Data.Stream as Stream
import qualified Streamly.Internal.Data.Stream.IsStream as Internal
import qualified Streamly.Internal.Data.Fold as FL
import qualified Streamly.Internal.Data.Unfold as Unfold
import qualified Prelude
import Gauge
import Streamly.Prelude (SerialT, fromSerial, MonadAsync)
import Streamly.Internal.Data.Stream.Serial (SerialT)
import Stream.Common hiding (scanl')
import Streamly.Benchmark.Common
import Streamly.Benchmark.Prelude
import Streamly.Internal.Data.Time.Units
import Prelude hiding (sequence, mapM, fmap)
import Prelude hiding (sequence, mapM)
-------------------------------------------------------------------------------
-- Pipelines (stream-to-stream transformations)
@ -94,83 +101,84 @@ o_n_space_traversable value =
-- maps and scans
-------------------------------------------------------------------------------
#ifdef USE_PRELUDE
{-# INLINE scanl' #-}
scanl' :: MonadIO m => Int -> SerialT m Int -> m ()
scanl' n = composeN n $ S.scanl' (+) 0
scanl' n = composeN n $ Stream.scanl' (+) 0
{-# INLINE scanlM' #-}
scanlM' :: MonadIO m => Int -> SerialT m Int -> m ()
scanlM' n = composeN n $ S.scanlM' (\b a -> return $ b + a) (return 0)
scanlM' n = composeN n $ Stream.scanlM' (\b a -> return $ b + a) (return 0)
{-# INLINE scanl1' #-}
scanl1' :: MonadIO m => Int -> SerialT m Int -> m ()
scanl1' n = composeN n $ S.scanl1' (+)
scanl1' n = composeN n $ Stream.scanl1' (+)
{-# INLINE scanl1M' #-}
scanl1M' :: MonadIO m => Int -> SerialT m Int -> m ()
scanl1M' n = composeN n $ S.scanl1M' (\b a -> return $ b + a)
scanl1M' n = composeN n $ Stream.scanl1M' (\b a -> return $ b + a)
#endif
{-# INLINE scan #-}
scan :: MonadIO m => Int -> SerialT m Int -> m ()
scan n = composeN n $ S.scan FL.sum
scan n = composeN n $ Stream.scan FL.sum
#ifdef USE_PRELUDE
{-# INLINE postscanl' #-}
postscanl' :: MonadIO m => Int -> SerialT m Int -> m ()
postscanl' n = composeN n $ S.postscanl' (+) 0
postscanl' n = composeN n $ Stream.postscanl' (+) 0
{-# INLINE postscanlM' #-}
postscanlM' :: MonadIO m => Int -> SerialT m Int -> m ()
postscanlM' n = composeN n $ S.postscanlM' (\b a -> return $ b + a) (return 0)
postscanlM' n = composeN n $ Stream.postscanlM' (\b a -> return $ b + a) (return 0)
#endif
{-# INLINE postscan #-}
postscan :: MonadIO m => Int -> SerialT m Int -> m ()
postscan n = composeN n $ S.postscan FL.sum
postscan n = composeN n $ Stream.postscan FL.sum
{-# INLINE sequence #-}
sequence ::
(S.IsStream t, S.MonadAsync m)
=> (t m Int -> S.SerialT m Int)
-> t m (m Int)
-> m ()
sequence t = S.drain . t . S.sequence
sequence :: MonadAsync m => SerialT m (m Int) -> m ()
sequence = Common.drain . Stream.sequence
{-# INLINE tap #-}
tap :: MonadIO m => Int -> SerialT m Int -> m ()
tap n = composeN n $ S.tap FL.sum
tap n = composeN n $ Stream.tap FL.sum
#ifdef USE_PRELUDE
{-# INLINE pollCounts #-}
pollCounts :: Int -> SerialT IO Int -> IO ()
pollCounts n =
composeN n (Internal.pollCounts (const True) f)
composeN n (Stream.pollCounts (const True) f)
where
f = S.drain . Internal.rollingMap2 (-) . Internal.delayPost 1
f = Stream.drain . Stream.rollingMap2 (-) . Stream.delayPost 1
{-# INLINE timestamped #-}
timestamped :: (S.MonadAsync m) => SerialT m Int -> m ()
timestamped = S.drain . Internal.timestamped
timestamped :: (MonadAsync m) => SerialT m Int -> m ()
timestamped = Stream.drain . Stream.timestamped
#endif
{-# INLINE foldrS #-}
foldrS :: MonadIO m => Int -> SerialT m Int -> m ()
foldrS n = composeN n $ Internal.foldrS S.cons S.nil
foldrS n = composeN n $ Stream.foldrS Stream.cons Stream.nil
{-# INLINE foldrSMap #-}
foldrSMap :: MonadIO m => Int -> SerialT m Int -> m ()
foldrSMap n = composeN n $ Internal.foldrS (\x xs -> x + 1 `S.cons` xs) S.nil
foldrSMap n = composeN n $ Stream.foldrS (\x xs -> x + 1 `Stream.cons` xs) Stream.nil
{-# INLINE foldrT #-}
foldrT :: MonadIO m => Int -> SerialT m Int -> m ()
foldrT n = composeN n $ Internal.foldrT S.cons S.nil
foldrT n = composeN n $ Stream.foldrT Stream.cons Stream.nil
{-# INLINE foldrTMap #-}
foldrTMap :: MonadIO m => Int -> SerialT m Int -> m ()
foldrTMap n = composeN n $ Internal.foldrT (\x xs -> x + 1 `S.cons` xs) S.nil
foldrTMap n = composeN n $ Stream.foldrT (\x xs -> x + 1 `Stream.cons` xs) Stream.nil
{-# INLINE trace #-}
trace :: MonadAsync m => Int -> SerialT m Int -> m ()
trace n = composeN n $ Internal.trace return
trace n = composeN n $ Stream.trace return
o_1_space_mapping :: Int -> [Benchmark]
o_1_space_mapping value =
@ -184,11 +192,12 @@ o_1_space_mapping value =
, benchIOSink value "foldrTMap" (foldrTMap 1)
-- Mapping
, benchIOSink value "map" (mapN fromSerial 1)
, benchIOSink value "map" (mapN 1)
, bench "sequence" $ nfIO $ randomRIO (1, 1000) >>= \n ->
sequence fromSerial (sourceUnfoldrAction value n)
, benchIOSink value "mapM" (mapM fromSerial 1)
sequence (sourceUnfoldrAction value n)
, benchIOSink value "mapM" (mapM 1)
, benchIOSink value "tap" (tap 1)
#ifdef USE_PRELUDE
, benchIOSink value "pollCounts 1 second" (pollCounts 1)
, benchIOSink value "timestamped" timestamped
@ -199,7 +208,7 @@ o_1_space_mapping value =
, benchIOSink value "scanl1M'" (scanl1M' 1)
, benchIOSink value "postscanl'" (postscanl' 1)
, benchIOSink value "postscanlM'" (postscanlM' 1)
#endif
, benchIOSink value "scan" (scan 1)
, benchIOSink value "postscan" (postscan 1)
]
@ -208,36 +217,37 @@ o_1_space_mapping value =
o_1_space_mappingX4 :: Int -> [Benchmark]
o_1_space_mappingX4 value =
[ bgroup "mappingX4"
[ benchIOSink value "map" (mapN fromSerial 4)
, benchIOSink value "mapM" (mapM fromSerial 4)
[ benchIOSink value "map" (mapN 4)
, benchIOSink value "mapM" (mapM 4)
, benchIOSink value "trace" (trace 4)
#ifdef USE_PRELUDE
, benchIOSink value "scanl'" (scanl' 4)
, benchIOSink value "scanl1'" (scanl1' 4)
, benchIOSink value "scanlM'" (scanlM' 4)
, benchIOSink value "scanl1M'" (scanl1M' 4)
, benchIOSink value "postscanl'" (postscanl' 4)
, benchIOSink value "postscanlM'" (postscanlM' 4)
#endif
]
]
{-# INLINE sieveScan #-}
sieveScan :: Monad m => SerialT m Int -> SerialT m Int
sieveScan =
S.mapMaybe snd
. S.scanlM' (\(primes, _) n -> do
Stream.mapMaybe snd
. Stream.scan (FL.foldlM' (\(primes, _) n -> do
return $
let ps = takeWhile (\p -> p * p <= n) primes
in if all (\p -> n `mod` p /= 0) ps
then (primes ++ [n], Just n)
else (primes, Nothing)) (return ([2], Just 2))
else (primes, Nothing)) (return ([2], Just 2)))
o_n_space_mapping :: Int -> [Benchmark]
o_n_space_mapping value =
[ bgroup "mapping"
[ benchIO "naive prime sieve"
(\n -> S.sum $ sieveScan $ S.enumerateFromTo 2 (value + n))
(\n -> Stream.fold FL.sum $ sieveScan $ Common.enumerateFromTo 2 (value + n))
]
]
@ -248,8 +258,8 @@ o_n_space_mapping value =
o_1_space_functor :: Int -> [Benchmark]
o_1_space_functor value =
[ bgroup "Functor"
[ benchIOSink value "fmap" (fmapN fromSerial 1)
, benchIOSink value "fmap x 4" (fmapN fromSerial 4)
[ benchIOSink value "fmap" (mapN 1)
, benchIOSink value "fmap x 4" (mapN 4)
]
]
@ -259,124 +269,124 @@ o_1_space_functor value =
{-# INLINE filterEven #-}
filterEven :: MonadIO m => Int -> SerialT m Int -> m ()
filterEven n = composeN n $ S.filter even
filterEven n = composeN n $ Stream.filter even
{-# INLINE filterAllOut #-}
filterAllOut :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
filterAllOut value n = composeN n $ S.filter (> (value + 1))
filterAllOut value n = composeN n $ Stream.filter (> (value + 1))
{-# INLINE filterAllIn #-}
filterAllIn :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
filterAllIn value n = composeN n $ S.filter (<= (value + 1))
filterAllIn value n = composeN n $ Stream.filter (<= (value + 1))
{-# INLINE filterMEven #-}
filterMEven :: MonadIO m => Int -> SerialT m Int -> m ()
filterMEven n = composeN n $ S.filterM (return . even)
filterMEven n = composeN n $ Stream.filterM (return . even)
{-# INLINE filterMAllOut #-}
filterMAllOut :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
filterMAllOut value n = composeN n $ S.filterM (\x -> return $ x > (value + 1))
filterMAllOut value n = composeN n $ Stream.filterM (\x -> return $ x > (value + 1))
{-# INLINE filterMAllIn #-}
filterMAllIn :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
filterMAllIn value n = composeN n $ S.filterM (\x -> return $ x <= (value + 1))
{-# INLINE foldFilterEven #-}
foldFilterEven :: MonadIO m => Int -> SerialT m Int -> m ()
foldFilterEven n = composeN n $ Stream.foldFilter (FL.satisfy even)
filterMAllIn value n = composeN n $ Stream.filterM (\x -> return $ x <= (value + 1))
{-# INLINE _takeOne #-}
_takeOne :: MonadIO m => Int -> SerialT m Int -> m ()
_takeOne n = composeN n $ S.take 1
_takeOne n = composeN n $ Stream.take 1
{-# INLINE takeAll #-}
takeAll :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
takeAll value n = composeN n $ S.take (value + 1)
takeAll value n = composeN n $ Stream.take (value + 1)
{-# INLINE takeWhileTrue #-}
takeWhileTrue :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
takeWhileTrue value n = composeN n $ S.takeWhile (<= (value + 1))
takeWhileTrue value n = composeN n $ Stream.takeWhile (<= (value + 1))
{-# INLINE takeWhileMTrue #-}
takeWhileMTrue :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
takeWhileMTrue value n = composeN n $ S.takeWhileM (return . (<= (value + 1)))
takeWhileMTrue value n = composeN n $ Stream.takeWhileM (return . (<= (value + 1)))
#ifdef USE_PRELUDE
{-# INLINE takeInterval #-}
takeInterval :: NanoSecond64 -> Int -> SerialT IO Int -> IO ()
takeInterval i n = composeN n (Internal.takeInterval i)
takeInterval i n = composeN n (Stream.takeInterval i)
#ifdef INSPECTION
-- inspect $ hasNoType 'takeInterval ''SPEC
inspect $ hasNoTypeClasses 'takeInterval
-- inspect $ 'takeInterval `hasNoType` ''D.Step
#endif
#endif
{-# INLINE dropOne #-}
dropOne :: MonadIO m => Int -> SerialT m Int -> m ()
dropOne n = composeN n $ S.drop 1
dropOne n = composeN n $ Stream.drop 1
{-# INLINE dropAll #-}
dropAll :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
dropAll value n = composeN n $ S.drop (value + 1)
dropAll value n = composeN n $ Stream.drop (value + 1)
{-# INLINE dropWhileTrue #-}
dropWhileTrue :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
dropWhileTrue value n = composeN n $ S.dropWhile (<= (value + 1))
dropWhileTrue value n = composeN n $ Stream.dropWhile (<= (value + 1))
{-# INLINE dropWhileMTrue #-}
dropWhileMTrue :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
dropWhileMTrue value n = composeN n $ S.dropWhileM (return . (<= (value + 1)))
dropWhileMTrue value n = composeN n $ Stream.dropWhileM (return . (<= (value + 1)))
{-# INLINE dropWhileFalse #-}
dropWhileFalse :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
dropWhileFalse value n = composeN n $ S.dropWhile (> (value + 1))
dropWhileFalse value n = composeN n $ Stream.dropWhile (> (value + 1))
#ifdef USE_PRELUDE
-- XXX Decide on the time interval
{-# INLINE _intervalsOfSum #-}
_intervalsOfSum :: MonadAsync m => Double -> Int -> SerialT m Int -> m ()
_intervalsOfSum i n = composeN n (S.intervalsOf i FL.sum)
_intervalsOfSum i n = composeN n (Stream.intervalsOf i FL.sum)
{-# INLINE dropInterval #-}
dropInterval :: NanoSecond64 -> Int -> SerialT IO Int -> IO ()
dropInterval i n = composeN n (Internal.dropInterval i)
dropInterval i n = composeN n (Stream.dropInterval i)
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'dropInterval
-- inspect $ 'dropInterval `hasNoType` ''D.Step
#endif
#endif
{-# INLINE findIndices #-}
findIndices :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
findIndices value n = composeN n $ S.findIndices (== (value + 1))
findIndices value n = composeN n $ Stream.findIndices (== (value + 1))
{-# INLINE elemIndices #-}
elemIndices :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
elemIndices value n = composeN n $ S.elemIndices (value + 1)
elemIndices value n = composeN n $ Stream.elemIndices (value + 1)
{-# INLINE deleteBy #-}
deleteBy :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
deleteBy value n = composeN n $ S.deleteBy (>=) (value + 1)
deleteBy value n = composeN n $ Stream.deleteBy (>=) (value + 1)
-- uniq . uniq == uniq, composeN 2 ~ composeN 1
{-# INLINE uniq #-}
uniq :: MonadIO m => Int -> SerialT m Int -> m ()
uniq n = composeN n S.uniq
uniq n = composeN n Stream.uniq
{-# INLINE mapMaybe #-}
mapMaybe :: MonadIO m => Int -> SerialT m Int -> m ()
mapMaybe n =
composeN n $
S.mapMaybe
Stream.mapMaybe
(\x ->
if odd x
then Nothing
else Just x)
{-# INLINE mapMaybeM #-}
mapMaybeM :: S.MonadAsync m => Int -> SerialT m Int -> m ()
mapMaybeM :: MonadAsync m => Int -> SerialT m Int -> m ()
mapMaybeM n =
composeN n $
S.mapMaybeM
Stream.mapMaybeM
(\x ->
if odd x
then return Nothing
@ -393,22 +403,22 @@ o_1_space_filtering value =
, benchIOSink value "filterM-all-out" (filterMAllOut value 1)
, benchIOSink value "filterM-all-in" (filterMAllIn value 1)
, benchIOSink value "foldFilter-even" (foldFilterEven 1)
-- Trimming
, benchIOSink value "take-all" (takeAll value 1)
, benchIOSink
value
"takeInterval-all"
(takeInterval (NanoSecond64 maxBound) 1)
, benchIOSink value "takeWhile-true" (takeWhileTrue value 1)
-- , benchIOSink value "takeWhileM-true" (_takeWhileMTrue value 1)
, benchIOSink value "drop-one" (dropOne 1)
, benchIOSink value "drop-all" (dropAll value 1)
#ifdef USE_PRELUDE
, benchIOSink
value
"takeInterval-all"
(takeInterval (NanoSecond64 maxBound) 1)
, benchIOSink
value
"dropInterval-all"
(dropInterval (NanoSecond64 maxBound) 1)
#endif
, benchIOSink value "dropWhile-true" (dropWhileTrue value 1)
-- , benchIOSink value "dropWhileM-true" (_dropWhileMTrue value 1)
, benchIOSink
@ -440,8 +450,6 @@ o_1_space_filteringX4 value =
, benchIOSink value "filterM-all-out" (filterMAllOut value 4)
, benchIOSink value "filterM-all-in" (filterMAllIn value 4)
, benchIOSink value "foldFilter-even" (foldFilterEven 4)
-- trimming
, benchIOSink value "take-all" (takeAll value 4)
, benchIOSink value "takeWhile-true" (takeWhileTrue value 4)
@ -473,26 +481,26 @@ o_1_space_filteringX4 value =
-------------------------------------------------------------------------------
{-# INLINE intersperse #-}
intersperse :: S.MonadAsync m => Int -> Int -> SerialT m Int -> m ()
intersperse value n = composeN n $ S.intersperse (value + 1)
intersperse :: MonadAsync m => Int -> Int -> SerialT m Int -> m ()
intersperse value n = composeN n $ Stream.intersperse (value + 1)
{-# INLINE intersperseM #-}
intersperseM :: S.MonadAsync m => Int -> Int -> SerialT m Int -> m ()
intersperseM value n = composeN n $ S.intersperseM (return $ value + 1)
intersperseM :: MonadAsync m => Int -> Int -> SerialT m Int -> m ()
intersperseM value n = composeN n $ Stream.intersperseM (return $ value + 1)
{-# INLINE insertBy #-}
insertBy :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
insertBy value n = composeN n $ S.insertBy compare (value + 1)
insertBy value n = composeN n $ Stream.insertBy compare (value + 1)
{-# INLINE interposeSuffix #-}
interposeSuffix :: S.MonadAsync m => Int -> Int -> SerialT m Int -> m ()
interposeSuffix :: Monad m => Int -> Int -> SerialT m Int -> m ()
interposeSuffix value n =
composeN n $ Internal.interposeSuffix (value + 1) Unfold.identity
composeN n $ Stream.interposeSuffix (value + 1) Unfold.identity
{-# INLINE intercalateSuffix #-}
intercalateSuffix :: S.MonadAsync m => Int -> Int -> SerialT m Int -> m ()
intercalateSuffix :: Monad m => Int -> Int -> SerialT m Int -> m ()
intercalateSuffix value n =
composeN n $ Internal.intercalateSuffix Unfold.identity (value + 1)
composeN n $ Stream.intercalateSuffix Unfold.identity (value + 1)
o_1_space_inserting :: Int -> [Benchmark]
o_1_space_inserting value =
@ -519,11 +527,11 @@ o_1_space_insertingX4 value =
{-# INLINE indexed #-}
indexed :: MonadIO m => Int -> SerialT m Int -> m ()
indexed n = composeN n (S.map snd . S.indexed)
indexed n = composeN n (fmap snd . Stream.indexed)
{-# INLINE indexedR #-}
indexedR :: MonadIO m => Int -> Int -> SerialT m Int -> m ()
indexedR value n = composeN n (S.map snd . S.indexedR value)
indexedR value n = composeN n (fmap snd . Stream.indexedR value)
o_1_space_indexing :: Int -> [Benchmark]
o_1_space_indexing value =

View File

@ -35,22 +35,22 @@ rtsOpts exeName benchName0 = unwords [general, exeSpecific, benchSpecific]
`isPrefixOf` benchName = "-K2M -M256M"
| "Prelude.Rate/o-1-space." `isPrefixOf` benchName = "-K128K"
| "Prelude.Rate/o-1-space.asyncly." `isPrefixOf` benchName = "-K128K"
| "Prelude.Serial/o-1-space.mixed.sum-product-fold" == benchName =
| "Data.Stream/o-1-space.mixed.sum-product-fold" == benchName =
"-K64M"
| "Prelude.Serial/o-n-heap.grouping.classifySessionsOf"
| "Data.Stream/o-n-heap.grouping.classifySessionsOf"
`isPrefixOf` benchName = "-K1M -M32M"
| "Prelude.Serial/o-n-heap.Functor." `isPrefixOf` benchName =
| "Data.Stream/o-n-heap.Functor." `isPrefixOf` benchName =
"-K4M -M32M"
| "Prelude.Serial/o-n-heap.transformer." `isPrefixOf` benchName =
| "Data.Stream/o-n-heap.transformer." `isPrefixOf` benchName =
"-K8M -M64M"
| "Prelude.Serial/o-n-space.Functor." `isPrefixOf` benchName =
| "Data.Stream/o-n-space.Functor." `isPrefixOf` benchName =
"-K4M -M64M"
| "Prelude.Serial/o-n-space.Applicative." `isPrefixOf` benchName =
| "Data.Stream/o-n-space.Applicative." `isPrefixOf` benchName =
"-K8M -M128M"
| "Prelude.Serial/o-n-space.Monad." `isPrefixOf` benchName =
| "Data.Stream/o-n-space.Monad." `isPrefixOf` benchName =
"-K8M -M64M"
| "Prelude.Serial/o-n-space.grouping." `isPrefixOf` benchName = ""
| "Prelude.Serial/o-n-space." `isPrefixOf` benchName = "-K4M"
| "Data.Stream/o-n-space.grouping." `isPrefixOf` benchName = ""
| "Data.Stream/o-n-space." `isPrefixOf` benchName = "-K4M"
| "Prelude.WSerial/o-n-space." `isPrefixOf` benchName = "-K4M"
| "Prelude.Async/o-n-space.monad-outer-product." `isPrefixOf` benchName =
"-K4M"

View File

@ -64,6 +64,11 @@ flag bench-core
manual: True
default: False
flag use-prelude
description: Use Prelude instead of Data.Stream for serial benchmarks
manual: True
default: False
-------------------------------------------------------------------------------
-- Common stanzas
-------------------------------------------------------------------------------
@ -71,6 +76,9 @@ flag bench-core
common compile-options
default-language: Haskell2010
if flag(use-prelude)
cpp-options: -DUSE_PRELUDE
if flag(dev)
cpp-options: -DDEVBUILD
@ -201,20 +209,23 @@ common bench-options-threaded
-- Serial Streams
-------------------------------------------------------------------------------
benchmark Prelude.Serial
benchmark Data.Stream
import: bench-options
type: exitcode-stdio-1.0
hs-source-dirs: Streamly/Benchmark/Prelude
main-is: Serial.hs
hs-source-dirs: Streamly/Benchmark/Data
main-is: Stream.hs
other-modules:
Serial.Generation
, Serial.Elimination
, Serial.Transformation
, Serial.NestedStream
, Serial.NestedFold
, Serial.Split
, Serial.Exceptions
, Serial.Lift
Stream.Generate
Stream.Eliminate
Stream.Transform
Stream.Reduce
Stream.Expand
Stream.Exceptions
Stream.Lift
Stream.Common
if flag(use-prelude)
other-modules:
Stream.Split
if flag(bench-core) || impl(ghcjs)
buildable: False
else
@ -225,7 +236,6 @@ benchmark Prelude.Serial
else
ghc-options: +RTS -M2500M -RTS
benchmark Prelude.WSerial
import: bench-options
type: exitcode-stdio-1.0

View File

@ -30,6 +30,16 @@ cradle:
component: "bench:Data.Stream.StreamD"
- path: "./benchmark/Streamly/Benchmark/Data/Stream/StreamK.hs"
component: "bench:Data.Stream.StreamK"
- path: "./benchmark/Streamly/Benchmark/Data/Stream/Common.hs"
component: "bench:Data.Stream"
- path: "./benchmark/Streamly/Benchmark/Data/Stream/Expand.hs"
component: "bench:Data.Stream"
- path: "./benchmark/Streamly/Benchmark/Data/Stream/Generate.hs"
component: "bench:Data.Stream"
- path: "./benchmark/Streamly/Benchmark/Data/Stream/Reduce.hs"
component: "bench:Data.Stream"
- path: "./benchmark/Streamly/Benchmark/Data/Stream/Transform.hs"
component: "bench:Data.Stream"
- path: "./benchmark/Streamly/Benchmark/Data/Unfold.hs"
component: "bench:Data.Unfold"
- path: "./benchmark/Streamly/Benchmark/FileSystem/Handle/Read.hs"
@ -44,24 +54,6 @@ cradle:
component: "bench:Prelude.Merge"
- path: "./benchmark/Streamly/Benchmark/Prelude/Parallel.hs"
component: "bench:Prelude.Parallel"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Elimination.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Exceptions.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Generation.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial/NestedStream.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Split.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Transformation.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial/NestedFold.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/Serial/Lift.hs"
component: "bench:Prelude.Serial"
- path: "./benchmark/Streamly/Benchmark/Prelude/WSerial.hs"
component: "bench:Prelude.WSerial"
- path: "./benchmark/Streamly/Benchmark/Prelude/ZipSerial.hs"

View File

@ -65,7 +65,6 @@ extra-source-files:
benchmark/Streamly/Benchmark/FileSystem/*.hs
benchmark/Streamly/Benchmark/FileSystem/Handle/*.hs
benchmark/Streamly/Benchmark/Prelude/*.hs
benchmark/Streamly/Benchmark/Prelude/Serial/*.hs
benchmark/Streamly/Benchmark/Unicode/*.hs
benchmark/lib/Streamly/Benchmark/*.hs
benchmark/lib/Streamly/Benchmark/Common/*.hs

View File

@ -25,9 +25,9 @@ targets =
)
-- Streams
, ("Prelude.Serial", ["serial_wserial_cmp"])
, ("Data.Stream", ["serial_wserial_cmp"])
, ("Prelude.WSerial", ["serial_wserial_cmp"])
, ("Prelude.Serial",
, ("Data.Stream",
[ "prelude_serial_grp"
, "infinite_grp"
, "serial_wserial_cmp"