mirror of
https://github.com/composewell/streamly.git
synced 2024-11-10 12:47:22 +03:00
432 lines
18 KiB
Haskell
432 lines
18 KiB
Haskell
{-# LANGUAGE CPP #-}
|
|
#if __GLASGOW_HASKELL__ >= 800
|
|
{-# OPTIONS_GHC -Wno-orphans #-}
|
|
#endif
|
|
|
|
-- |
|
|
-- Module : Main
|
|
-- Copyright : (c) 2018 Harendra Kumar
|
|
--
|
|
-- License : BSD3
|
|
-- Maintainer : harendra.kumar@gmail.com
|
|
|
|
import Control.DeepSeq (NFData(..), deepseq)
|
|
import Data.Functor.Identity (Identity, runIdentity)
|
|
import System.Random (randomRIO)
|
|
import Data.Monoid (Last(..))
|
|
|
|
import qualified GHC.Exts as GHC
|
|
import qualified Streamly.Benchmark.Prelude as Ops
|
|
|
|
import Streamly
|
|
import qualified Streamly.Data.Fold as FL
|
|
import qualified Streamly.Memory.Array as A
|
|
import qualified Streamly.Prelude as S
|
|
import qualified Streamly.Internal.Data.Sink as Sink
|
|
|
|
import qualified Streamly.Internal.Data.Fold as IFL
|
|
import qualified Streamly.Internal.Prelude as IP
|
|
import qualified Streamly.Internal.Data.Pipe as Pipe
|
|
|
|
import Gauge
|
|
|
|
-------------------------------------------------------------------------------
|
|
--
|
|
-------------------------------------------------------------------------------
|
|
|
|
#if !MIN_VERSION_deepseq(1,4,3)
|
|
instance NFData Ordering where rnf = (`seq` ())
|
|
#endif
|
|
|
|
-- We need a monadic bind here to make sure that the function f does not get
|
|
-- completely optimized out by the compiler in some cases.
|
|
|
|
-- | Takes a fold method, and uses it with a default source.
|
|
{-# INLINE benchIOSink #-}
|
|
benchIOSink
|
|
:: (IsStream t, NFData b)
|
|
=> String -> (t IO Int -> IO b) -> Benchmark
|
|
benchIOSink name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source
|
|
|
|
-- XXX once we convert all the functions to use this we can rename this to
|
|
-- benchIOSink
|
|
{-# INLINE benchIOSink1 #-}
|
|
benchIOSink1 :: NFData b => String -> (Int -> IO b) -> Benchmark
|
|
benchIOSink1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
|
|
|
|
-- XXX We should be using sourceUnfoldrM for fair comparison with IO monad, but
|
|
-- we can't use it as it requires MonadAsync constraint.
|
|
{-# INLINE benchIdentitySink #-}
|
|
benchIdentitySink
|
|
:: (IsStream t, NFData b)
|
|
=> String -> (t Identity Int -> Identity b) -> Benchmark
|
|
benchIdentitySink name f = bench name $ nf (f . Ops.sourceUnfoldr) 1
|
|
|
|
-- | Takes a source, and uses it with a default drain/fold method.
|
|
{-# INLINE benchIOSrc #-}
|
|
benchIOSrc
|
|
:: (t IO a -> SerialT IO a)
|
|
-> String
|
|
-> (Int -> t IO a)
|
|
-> Benchmark
|
|
benchIOSrc t name f =
|
|
bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
|
|
|
|
{-# INLINE benchIOSrc1 #-}
|
|
benchIOSrc1 :: String -> (Int -> IO ()) -> Benchmark
|
|
benchIOSrc1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
|
|
|
|
{-# INLINE benchPure #-}
|
|
benchPure :: NFData b => String -> (Int -> a) -> (a -> b) -> Benchmark
|
|
benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
|
|
|
|
{-# INLINE benchPureSink #-}
|
|
benchPureSink :: NFData b => String -> (SerialT Identity Int -> b) -> Benchmark
|
|
benchPureSink name f = benchPure name Ops.sourceUnfoldr f
|
|
|
|
-- XXX once we convert all the functions to use this we can rename this to
|
|
-- benchPureSink
|
|
{-# INLINE benchPureSink1 #-}
|
|
benchPureSink1 :: NFData b => String -> (Int -> Identity b) -> Benchmark
|
|
benchPureSink1 name f =
|
|
bench name $ nfIO $ randomRIO (1,1) >>= return . runIdentity . f
|
|
|
|
{-# INLINE benchPureSinkIO #-}
|
|
benchPureSinkIO
|
|
:: NFData b
|
|
=> String -> (SerialT Identity Int -> IO b) -> Benchmark
|
|
benchPureSinkIO name f =
|
|
bench name $ nfIO $ randomRIO (1, 1) >>= f . Ops.sourceUnfoldr
|
|
|
|
{-# INLINE benchPureSrc #-}
|
|
benchPureSrc :: String -> (Int -> SerialT Identity a) -> Benchmark
|
|
benchPureSrc name src = benchPure name src (runIdentity . S.drain)
|
|
|
|
mkString :: String
|
|
mkString = "fromList [1" ++ concat (replicate Ops.value ",1") ++ "]"
|
|
|
|
mkListString :: String
|
|
mkListString = "[1" ++ concat (replicate Ops.value ",1") ++ "]"
|
|
|
|
mkList :: [Int]
|
|
mkList = [1..Ops.value]
|
|
|
|
main :: IO ()
|
|
main =
|
|
defaultMain
|
|
[ bgroup "serially"
|
|
[ bgroup "pure"
|
|
[ benchPureSink "id" id
|
|
, benchPureSink1 "eqBy" Ops.eqByPure
|
|
, benchPureSink "==" Ops.eqInstance
|
|
, benchPureSink "/=" Ops.eqInstanceNotEq
|
|
, benchPureSink1 "cmpBy" Ops.cmpByPure
|
|
, benchPureSink "<" Ops.ordInstance
|
|
, benchPureSink "min" Ops.ordInstanceMin
|
|
, benchPureSrc "IsList.fromList" Ops.sourceIsList
|
|
-- length is used to check for foldr/build fusion
|
|
, benchPureSink "length . IsList.toList" (length . GHC.toList)
|
|
, benchPureSrc "IsString.fromString" Ops.sourceIsString
|
|
, mkString `deepseq` (bench "readsPrec pure streams" $
|
|
nf Ops.readInstance mkString)
|
|
, mkString `deepseq` (bench "readsPrec Haskell lists" $
|
|
nf Ops.readInstanceList mkListString)
|
|
, benchPureSink "showsPrec pure streams" Ops.showInstance
|
|
, mkList `deepseq` (bench "showPrec Haskell lists" $
|
|
nf Ops.showInstanceList mkList)
|
|
, benchPureSink "foldl'" Ops.pureFoldl'
|
|
, benchPureSink "foldable/foldl'" Ops.foldableFoldl'
|
|
, benchPureSink "foldable/sum" Ops.foldableSum
|
|
, benchPureSinkIO "traversable/mapM" Ops.traversableMapM
|
|
]
|
|
, bgroup "generation"
|
|
[ -- Most basic, barely stream continuations running
|
|
benchIOSrc serially "unfoldr" Ops.sourceUnfoldr
|
|
, benchIOSrc serially "unfoldrM" Ops.sourceUnfoldrM
|
|
, benchIOSrc serially "intFromTo" Ops.sourceIntFromTo
|
|
, benchIOSrc serially "intFromThenTo" Ops.sourceIntFromThenTo
|
|
, benchIOSrc serially "integerFromStep" Ops.sourceIntegerFromStep
|
|
, benchIOSrc serially "fracFromThenTo" Ops.sourceFracFromThenTo
|
|
, benchIOSrc serially "fracFromTo" Ops.sourceFracFromTo
|
|
, benchIOSrc serially "fromList" Ops.sourceFromList
|
|
, benchIOSrc serially "fromListM" Ops.sourceFromListM
|
|
-- These are essentially cons and consM
|
|
, benchIOSrc serially "fromFoldable" Ops.sourceFromFoldable
|
|
, benchIOSrc serially "fromFoldableM" Ops.sourceFromFoldableM
|
|
]
|
|
, bgroup "elimination"
|
|
[ bgroup "reduce"
|
|
[ bgroup "IO"
|
|
[ benchIOSink "foldrM" Ops.foldrMReduce
|
|
, benchIOSink "foldl'" Ops.foldl'Reduce
|
|
, benchIOSink "foldl1'" Ops.foldl1'Reduce
|
|
, benchIOSink "foldlM'" Ops.foldlM'Reduce
|
|
]
|
|
, bgroup "Identity"
|
|
[ benchIdentitySink "foldrM" Ops.foldrMReduce
|
|
, benchIdentitySink "foldl'" Ops.foldl'Reduce
|
|
, benchIdentitySink "foldl1'" Ops.foldl1'Reduce
|
|
, benchIdentitySink "foldlM'" Ops.foldlM'Reduce
|
|
]
|
|
]
|
|
|
|
, bgroup "build"
|
|
[ bgroup "IO"
|
|
[ benchIOSink "foldrM" Ops.foldrMBuild
|
|
, benchIOSink "foldl'" Ops.foldl'Build
|
|
, benchIOSink "foldlM'" Ops.foldlM'Build
|
|
]
|
|
, bgroup "Identity"
|
|
[ benchIdentitySink "foldrM" Ops.foldrMBuild
|
|
, benchIdentitySink "foldl'" Ops.foldl'Build
|
|
, benchIdentitySink "foldlM'" Ops.foldlM'Build
|
|
]
|
|
]
|
|
, benchIOSink "uncons" Ops.uncons
|
|
, benchIOSink "toNull" $ Ops.toNull serially
|
|
, benchIOSink "mapM_" Ops.mapM_
|
|
|
|
, benchIOSink "init" Ops.init
|
|
, benchIOSink "tail" Ops.tail
|
|
, benchIOSink "nullHeadTail" Ops.nullHeadTail
|
|
|
|
-- this is too low and causes all benchmarks reported in ns
|
|
-- , benchIOSink "head" Ops.head
|
|
, benchIOSink "last" Ops.last
|
|
-- , benchIOSink "lookup" Ops.lookup
|
|
, benchIOSink "find" Ops.find
|
|
, benchIOSink "findIndex" Ops.findIndex
|
|
, benchIOSink "elemIndex" Ops.elemIndex
|
|
|
|
-- this is too low and causes all benchmarks reported in ns
|
|
-- , benchIOSink "null" Ops.null
|
|
, benchIOSink "elem" Ops.elem
|
|
, benchIOSink "notElem" Ops.notElem
|
|
, benchIOSink "all" Ops.all
|
|
, benchIOSink "any" Ops.any
|
|
, benchIOSink "and" Ops.and
|
|
, benchIOSink "or" Ops.or
|
|
|
|
, benchIOSink "length" Ops.length
|
|
, benchIOSink "sum" Ops.sum
|
|
, benchIOSink "product" Ops.product
|
|
|
|
, benchIOSink "maximumBy" Ops.maximumBy
|
|
, benchIOSink "maximum" Ops.maximum
|
|
, benchIOSink "minimumBy" Ops.minimumBy
|
|
, benchIOSink "minimum" Ops.minimum
|
|
|
|
, benchIOSink "toList" Ops.toList
|
|
, benchIOSink "toListRev" Ops.toListRev
|
|
]
|
|
, bgroup "folds"
|
|
[ benchIOSink "drain" (S.fold FL.drain)
|
|
, benchIOSink "sink" (S.fold $ Sink.toFold Sink.drain)
|
|
, benchIOSink "last" (S.fold FL.last)
|
|
, benchIOSink "length" (S.fold FL.length)
|
|
, benchIOSink "sum" (S.fold FL.sum)
|
|
, benchIOSink "product" (S.fold FL.product)
|
|
, benchIOSink "maximumBy" (S.fold (FL.maximumBy compare))
|
|
, benchIOSink "maximum" (S.fold FL.maximum)
|
|
, benchIOSink "minimumBy" (S.fold (FL.minimumBy compare))
|
|
, benchIOSink "minimum" (S.fold FL.minimum)
|
|
, benchIOSink "mean" (\s -> S.fold FL.mean (S.map (fromIntegral :: Int -> Double) s))
|
|
, benchIOSink "variance" (\s -> S.fold FL.variance (S.map (fromIntegral :: Int -> Double) s))
|
|
, benchIOSink "stdDev" (\s -> S.fold FL.stdDev (S.map (fromIntegral :: Int -> Double) s))
|
|
|
|
, benchIOSink "mconcat" (S.fold FL.mconcat . (S.map (Last . Just)))
|
|
, benchIOSink "foldMap" (S.fold (FL.foldMap (Last . Just)))
|
|
|
|
, benchIOSink "toList" (S.fold FL.toList)
|
|
, benchIOSink "toListRevF" (S.fold IFL.toListRevF)
|
|
, benchIOSink "toStream" (S.fold IP.toStream)
|
|
, benchIOSink "toStreamRev" (S.fold IP.toStreamRev)
|
|
, benchIOSink "writeN" (S.fold (A.writeN Ops.value))
|
|
|
|
, benchIOSink "index" (S.fold (FL.index Ops.maxValue))
|
|
, benchIOSink "head" (S.fold FL.head)
|
|
, benchIOSink "find" (S.fold (FL.find (== Ops.maxValue)))
|
|
, benchIOSink "findIndex" (S.fold (FL.findIndex (== Ops.maxValue)))
|
|
, benchIOSink "elemIndex" (S.fold (FL.elemIndex Ops.maxValue))
|
|
|
|
, benchIOSink "null" (S.fold FL.null)
|
|
, benchIOSink "elem" (S.fold (FL.elem Ops.maxValue))
|
|
, benchIOSink "notElem" (S.fold (FL.notElem Ops.maxValue))
|
|
, benchIOSink "all" (S.fold (FL.all (<= Ops.maxValue)))
|
|
, benchIOSink "any" (S.fold (FL.any (> Ops.maxValue)))
|
|
, benchIOSink "and" (\s -> S.fold FL.and (S.map (<= Ops.maxValue) s))
|
|
, benchIOSink "or" (\s -> S.fold FL.or (S.map (> Ops.maxValue) s))
|
|
]
|
|
, bgroup "fold-multi-stream"
|
|
[ benchIOSink1 "eqBy" Ops.eqBy
|
|
, benchIOSink1 "cmpBy" Ops.cmpBy
|
|
, benchIOSink "isPrefixOf" Ops.isPrefixOf
|
|
, benchIOSink "isSubsequenceOf" Ops.isSubsequenceOf
|
|
, benchIOSink "stripPrefix" Ops.stripPrefix
|
|
]
|
|
, bgroup "folds-transforms"
|
|
[ benchIOSink "drain" (S.fold FL.drain)
|
|
, benchIOSink "lmap" (S.fold (IFL.lmap (+1) FL.drain))
|
|
, benchIOSink "pipe-mapM"
|
|
(S.fold (IFL.transform (Pipe.mapM (\x -> return $ x + 1)) FL.drain))
|
|
]
|
|
, bgroup "folds-compositions" -- Applicative
|
|
[
|
|
benchIOSink "all,any" (S.fold ((,) <$> FL.all (<= Ops.maxValue)
|
|
<*> FL.any (> Ops.maxValue)))
|
|
, benchIOSink "sum,length" (S.fold ((,) <$> FL.sum <*> FL.length))
|
|
]
|
|
, bgroup "pipes"
|
|
[ benchIOSink "mapM" (Ops.transformMapM serially 1)
|
|
, benchIOSink "compose" (Ops.transformComposeMapM serially 1)
|
|
, benchIOSink "tee" (Ops.transformTeeMapM serially 1)
|
|
, benchIOSink "zip" (Ops.transformZipMapM serially 1)
|
|
]
|
|
, bgroup "pipesX4"
|
|
[ benchIOSink "mapM" (Ops.transformMapM serially 4)
|
|
, benchIOSink "compose" (Ops.transformComposeMapM serially 4)
|
|
, benchIOSink "tee" (Ops.transformTeeMapM serially 4)
|
|
, benchIOSink "zip" (Ops.transformZipMapM serially 4)
|
|
]
|
|
, bgroup "transformation"
|
|
[ benchIOSink "scanl" (Ops.scan 1)
|
|
, benchIOSink "scanl1'" (Ops.scanl1' 1)
|
|
, benchIOSink "map" (Ops.map 1)
|
|
, benchIOSink "fmap" (Ops.fmap 1)
|
|
, benchIOSink "mapM" (Ops.mapM serially 1)
|
|
, benchIOSink "mapMaybe" (Ops.mapMaybe 1)
|
|
, benchIOSink "mapMaybeM" (Ops.mapMaybeM 1)
|
|
, bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
|
|
Ops.sequence serially (Ops.sourceUnfoldrMAction n)
|
|
, benchIOSink "findIndices" (Ops.findIndices 1)
|
|
, benchIOSink "elemIndices" (Ops.elemIndices 1)
|
|
, benchIOSink "reverse" (Ops.reverse 1)
|
|
, benchIOSink "reverse'" (Ops.reverse' 1)
|
|
, benchIOSink "foldrS" (Ops.foldrS 1)
|
|
, benchIOSink "foldrSMap" (Ops.foldrSMap 1)
|
|
, benchIOSink "foldrT" (Ops.foldrT 1)
|
|
, benchIOSink "foldrTMap" (Ops.foldrTMap 1)
|
|
]
|
|
, bgroup "transformationX4"
|
|
[ benchIOSink "scan" (Ops.scan 4)
|
|
, benchIOSink "scanl1'" (Ops.scanl1' 4)
|
|
, benchIOSink "map" (Ops.map 4)
|
|
, benchIOSink "fmap" (Ops.fmap 4)
|
|
, benchIOSink "mapM" (Ops.mapM serially 4)
|
|
, benchIOSink "mapMaybe" (Ops.mapMaybe 4)
|
|
, benchIOSink "mapMaybeM" (Ops.mapMaybeM 4)
|
|
-- , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
|
|
-- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
|
|
, benchIOSink "findIndices" (Ops.findIndices 4)
|
|
, benchIOSink "elemIndices" (Ops.elemIndices 4)
|
|
]
|
|
, bgroup "filtering"
|
|
[ benchIOSink "filter-even" (Ops.filterEven 1)
|
|
, benchIOSink "filter-all-out" (Ops.filterAllOut 1)
|
|
, benchIOSink "filter-all-in" (Ops.filterAllIn 1)
|
|
, benchIOSink "take-all" (Ops.takeAll 1)
|
|
, benchIOSink "takeWhile-true" (Ops.takeWhileTrue 1)
|
|
--, benchIOSink "takeWhileM-true" (Ops.takeWhileMTrue 1)
|
|
, benchIOSink "drop-one" (Ops.dropOne 1)
|
|
, benchIOSink "drop-all" (Ops.dropAll 1)
|
|
, benchIOSink "dropWhile-true" (Ops.dropWhileTrue 1)
|
|
--, benchIOSink "dropWhileM-true" (Ops.dropWhileMTrue 1)
|
|
, benchIOSink "dropWhile-false" (Ops.dropWhileFalse 1)
|
|
, benchIOSink "deleteBy" (Ops.deleteBy 1)
|
|
, benchIOSink "intersperse" (Ops.intersperse 1)
|
|
, benchIOSink "insertBy" (Ops.insertBy 1)
|
|
]
|
|
, bgroup "filteringX4"
|
|
[ benchIOSink "filter-even" (Ops.filterEven 4)
|
|
, benchIOSink "filter-all-out" (Ops.filterAllOut 4)
|
|
, benchIOSink "filter-all-in" (Ops.filterAllIn 4)
|
|
, benchIOSink "take-all" (Ops.takeAll 4)
|
|
, benchIOSink "takeWhile-true" (Ops.takeWhileTrue 4)
|
|
--, benchIOSink "takeWhileM-true" (Ops.takeWhileMTrue 4)
|
|
, benchIOSink "drop-one" (Ops.dropOne 4)
|
|
, benchIOSink "drop-all" (Ops.dropAll 4)
|
|
, benchIOSink "dropWhile-true" (Ops.dropWhileTrue 4)
|
|
--, benchIOSink "dropWhileM-true" (Ops.dropWhileMTrue 4)
|
|
, benchIOSink "dropWhile-false" (Ops.dropWhileFalse 4)
|
|
, benchIOSink "deleteBy" (Ops.deleteBy 4)
|
|
, benchIOSink "intersperse" (Ops.intersperse 4)
|
|
, benchIOSink "insertBy" (Ops.insertBy 4)
|
|
]
|
|
, bgroup "joining"
|
|
[ benchIOSrc1 "zip (2x50K)" (Ops.zip 50000)
|
|
, benchIOSrc1 "zipM (2x50K)" (Ops.zipM 50000)
|
|
, benchIOSrc1 "mergeBy (2x50K)" (Ops.mergeBy 50000)
|
|
, benchIOSrc1 "serial (2x50K)" (Ops.serial2 50000)
|
|
, benchIOSrc1 "append (2x50K)" (Ops.append2 50000)
|
|
, benchIOSrc1 "serial (2x2x25K)" (Ops.serial4 25000)
|
|
, benchIOSrc1 "append (2x2x25K)" (Ops.append4 25000)
|
|
, benchIOSrc1 "wSerial (2x50K)" Ops.wSerial2
|
|
, benchIOSrc1 "interleave (2x50K)" Ops.interleave2
|
|
, benchIOSrc1 "roundRobin (2x50K)" Ops.roundRobin2
|
|
]
|
|
, bgroup "concat-foldable"
|
|
[ benchIOSrc serially "foldMapWith (1x100K)" Ops.sourceFoldMapWith
|
|
, benchIOSrc serially "foldMapWithM (1x100K)" Ops.sourceFoldMapWithM
|
|
, benchIOSrc serially "foldMapM (1x100K)" Ops.sourceFoldMapM
|
|
, benchIOSrc serially "foldWithConcatMapId (1x100K)" Ops.sourceConcatMapId
|
|
]
|
|
, bgroup "concat-serial"
|
|
[ benchIOSrc1 "concatMapPure (2x50K)" (Ops.concatMapPure 2 50000)
|
|
, benchIOSrc1 "concatMap (2x50K)" (Ops.concatMap 2 50000)
|
|
, benchIOSrc1 "concatMap (50Kx2)" (Ops.concatMap 50000 2)
|
|
, benchIOSrc1 "concatMapRepl (25Kx4)" Ops.concatMapRepl4xN
|
|
, benchIOSrc1 "concatUnfoldRepl (25Kx4)" Ops.concatUnfoldRepl4xN
|
|
|
|
, benchIOSrc1 "concatMapWithSerial (2x50K)"
|
|
(Ops.concatMapWithSerial 2 50000)
|
|
, benchIOSrc1 "concatMapWithSerial (50Kx2)"
|
|
(Ops.concatMapWithSerial 50000 2)
|
|
|
|
, benchIOSrc1 "concatMapWithAppend (2x50K)"
|
|
(Ops.concatMapWithAppend 2 50000)
|
|
]
|
|
, bgroup "concat-interleave"
|
|
[ benchIOSrc1 "concatMapWithWSerial (2x50K)"
|
|
(Ops.concatMapWithWSerial 2 50000)
|
|
, benchIOSrc1 "concatMapWithWSerial (50Kx2)"
|
|
(Ops.concatMapWithWSerial 50000 2)
|
|
, benchIOSrc1 "concatUnfoldInterleaveRepl (25Kx4)"
|
|
Ops.concatUnfoldInterleaveRepl4xN
|
|
, benchIOSrc1 "concatUnfoldRoundrobinRepl (25Kx4)"
|
|
Ops.concatUnfoldRoundrobinRepl4xN
|
|
]
|
|
-- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
|
|
-- library. If scan/fold followed by a map is efficient enough we may not
|
|
-- need monolithic implementations of these.
|
|
, bgroup "mixed"
|
|
[ benchIOSink "scanl-map" (Ops.scanMap 1)
|
|
, benchIOSink "foldl-map" Ops.foldl'ReduceMap
|
|
, benchIOSink "sum-product-fold" Ops.sumProductFold
|
|
, benchIOSink "sum-product-scan" Ops.sumProductScan
|
|
]
|
|
, bgroup "mixedX4"
|
|
[ benchIOSink "scan-map" (Ops.scanMap 4)
|
|
, benchIOSink "drop-map" (Ops.dropMap 4)
|
|
, benchIOSink "drop-scan" (Ops.dropScan 4)
|
|
, benchIOSink "take-drop" (Ops.takeDrop 4)
|
|
, benchIOSink "take-scan" (Ops.takeScan 4)
|
|
, benchIOSink "take-map" (Ops.takeMap 4)
|
|
, benchIOSink "filter-drop" (Ops.filterDrop 4)
|
|
, benchIOSink "filter-take" (Ops.filterTake 4)
|
|
, benchIOSink "filter-scan" (Ops.filterScan 4)
|
|
, benchIOSink "filter-scanl1" (Ops.filterScanl1 4)
|
|
, benchIOSink "filter-map" (Ops.filterMap 4)
|
|
]
|
|
, bgroup "iterated"
|
|
[ benchIOSrc serially "mapM" Ops.iterateMapM
|
|
, benchIOSrc serially "scan(1/100)" Ops.iterateScan
|
|
, benchIOSrc serially "scanl1(1/100)" Ops.iterateScanl1
|
|
, benchIOSrc serially "filterEven" Ops.iterateFilterEven
|
|
, benchIOSrc serially "takeAll" Ops.iterateTakeAll
|
|
, benchIOSrc serially "dropOne" Ops.iterateDropOne
|
|
, benchIOSrc serially "dropWhileFalse" Ops.iterateDropWhileFalse
|
|
, benchIOSrc serially "dropWhileTrue" Ops.iterateDropWhileTrue
|
|
]
|
|
]
|
|
]
|