streamly/benchmark/Array.hs
2019-05-15 20:41:45 +05:30

250 lines
10 KiB
Haskell

{-# LANGUAGE CPP #-}
-- |
-- Module : Main
-- Copyright : (c) 2018 Harendra Kumar
--
-- License : BSD3
-- Maintainer : harendra.kumar@gmail.com
import Control.DeepSeq (NFData(..), deepseq)
import Foreign.Storable (Storable(..))
import System.Random (randomRIO)
import qualified GHC.Exts as GHC
import qualified ArrayOps as Ops
import qualified Streamly.Mem.Array as A
import qualified Streamly.Prelude as S
import Gauge
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
{-# INLINE benchPure #-}
benchPure :: NFData b => String -> (Int -> a) -> (a -> b) -> Benchmark
benchPure name src f = bench name $ nfIO $
randomRIO (1,1) >>= return . f . src
-- Drain a source that generates a pure array
{-# INLINE benchPureSrc #-}
benchPureSrc :: (NFData a, Storable a)
=> String -> (Int -> Ops.Stream a) -> Benchmark
benchPureSrc name src = benchPure name src id
{-# INLINE benchIO #-}
benchIO :: NFData b => String -> (Int -> IO a) -> (a -> b) -> Benchmark
benchIO name src f = bench name $ nfIO $
randomRIO (1,1) >>= src >>= return . f
-- Drain a source that generates an array in the IO monad
{-# INLINE benchIOSrc #-}
benchIOSrc :: (NFData a, Storable a)
=> String -> (Int -> IO (Ops.Stream a)) -> Benchmark
benchIOSrc name src = benchIO name src id
{-# INLINE benchPureSink #-}
benchPureSink :: NFData b => String -> (Ops.Stream Int -> b) -> Benchmark
benchPureSink name f = benchIO name Ops.sourceIntFromTo f
{-# INLINE benchIO' #-}
benchIO' :: NFData b => String -> (Int -> IO a) -> (a -> IO b) -> Benchmark
benchIO' name src f = bench name $ nfIO $
randomRIO (1,1) >>= src >>= f
{-# INLINE benchIOSink #-}
benchIOSink :: NFData b => String -> (Ops.Stream Int -> IO b) -> Benchmark
benchIOSink name f = benchIO' name Ops.sourceIntFromTo f
mkString :: String
mkString = "[1" ++ concat (replicate Ops.value ",1") ++ "]"
main :: IO ()
main =
defaultMain
[ bgroup "array"
[ bgroup "generation"
[ benchIOSrc "writeN . intFromTo" Ops.sourceIntFromTo
, benchIOSrc "write . intFromTo" Ops.sourceIntFromToFromStream
, benchIOSrc "fromList . intFromTo" Ops.sourceIntFromToFromList
, benchIOSrc "writeN . unfoldr" Ops.sourceUnfoldr
, benchIOSrc "writeN . fromList" Ops.sourceFromList
, benchPureSrc "writeN . IsList.fromList" Ops.sourceIsList
, benchPureSrc "writeN . IsString.fromString" Ops.sourceIsString
, mkString `deepseq` (bench "read" $ nf Ops.readInstance mkString)
, benchPureSink "show" Ops.showInstance
]
, bgroup "elimination"
[ benchPureSink "id" id
-- , benchPureSink "eqBy" Ops.eqBy
, benchPureSink "==" Ops.eqInstance
, benchPureSink "/=" Ops.eqInstanceNotEq
{-
, benchPureSink "cmpBy" Ops.cmpBy
-}
, benchPureSink "<" Ops.ordInstance
, benchPureSink "min" Ops.ordInstanceMin
, benchPureSink "IsList.toList" GHC.toList
, benchIOSink "foldl'" Ops.pureFoldl'
, benchIOSink "read" (S.drain . A.read)
, benchIOSink "readRev" (S.drain . A.readRev)
#ifdef DEVBUILD
, benchPureSink "foldable/foldl'" Ops.foldableFoldl'
, benchPureSink "foldable/sum" Ops.foldableSum
-- , benchPureSinkIO "traversable/mapM" Ops.traversableMapM
#endif
]
{-
[ benchPureSink "uncons" Ops.uncons
, benchPureSink "toNull" $ Ops.toNull serially
, benchPureSink "mapM_" Ops.mapM_
, benchPureSink "init" Ops.init
, benchPureSink "tail" Ops.tail
, benchPureSink "nullHeadTail" Ops.nullHeadTail
-- this is too low and causes all benchmarks reported in ns
-- , benchPureSink "head" Ops.head
, benchPureSink "last" Ops.last
-- , benchPureSink "lookup" Ops.lookup
, benchPureSink "find" Ops.find
, benchPureSink "findIndex" Ops.findIndex
, benchPureSink "elemIndex" Ops.elemIndex
-- this is too low and causes all benchmarks reported in ns
-- , benchPureSink "null" Ops.null
, benchPureSink "elem" Ops.elem
, benchPureSink "notElem" Ops.notElem
, benchPureSink "all" Ops.all
, benchPureSink "any" Ops.any
, benchPureSink "and" Ops.and
, benchPureSink "or" Ops.or
, benchPureSink "length" Ops.length
, benchPureSink "sum" Ops.sum
, benchPureSink "product" Ops.product
, benchPureSink "maximumBy" Ops.maximumBy
, benchPureSink "maximum" Ops.maximum
, benchPureSink "minimumBy" Ops.minimumBy
, benchPureSink "minimum" Ops.minimum
, benchPureSink "toList" Ops.toList
, benchPureSink "toRevList" Ops.toRevList
]
-}
, bgroup "transformation"
[ benchIOSink "scanl'" (Ops.scanl' 1)
, benchIOSink "scanl1'" (Ops.scanl1' 1)
, benchIOSink "map" (Ops.map 1)
{-
, benchPureSink "fmap" (Ops.fmap 1)
, benchPureSink "mapM" (Ops.mapM serially 1)
, benchPureSink "mapMaybe" (Ops.mapMaybe 1)
, benchPureSink "mapMaybeM" (Ops.mapMaybeM 1)
, bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
Ops.sequence serially (Ops.sourceUnfoldrMAction n)
, benchPureSink "findIndices" (Ops.findIndices 1)
, benchPureSink "elemIndices" (Ops.elemIndices 1)
, benchPureSink "reverse" (Ops.reverse 1)
, benchPureSink "foldrS" (Ops.foldrS 1)
, benchPureSink "foldrSMap" (Ops.foldrSMap 1)
, benchPureSink "foldrT" (Ops.foldrT 1)
, benchPureSink "foldrTMap" (Ops.foldrTMap 1)
-}
]
, bgroup "transformationX4"
[ benchIOSink "scanl'" (Ops.scanl' 4)
, benchIOSink "scanl1'" (Ops.scanl1' 4)
, benchIOSink "map" (Ops.map 4)
{-
, benchPureSink "fmap" (Ops.fmap 4)
, benchPureSink "mapM" (Ops.mapM serially 4)
, benchPureSink "mapMaybe" (Ops.mapMaybe 4)
, benchPureSink "mapMaybeM" (Ops.mapMaybeM 4)
-- , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
-- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
, benchPureSink "findIndices" (Ops.findIndices 4)
, benchPureSink "elemIndices" (Ops.elemIndices 4)
-}
]
{-
, bgroup "filtering"
[ benchPureSink "filter-even" (Ops.filterEven 1)
, benchPureSink "filter-all-out" (Ops.filterAllOut 1)
, benchPureSink "filter-all-in" (Ops.filterAllIn 1)
, benchPureSink "take-all" (Ops.takeAll 1)
, benchPureSink "takeWhile-true" (Ops.takeWhileTrue 1)
--, benchPureSink "takeWhileM-true" (Ops.takeWhileMTrue 1)
, benchPureSink "drop-one" (Ops.dropOne 1)
, benchPureSink "drop-all" (Ops.dropAll 1)
, benchPureSink "dropWhile-true" (Ops.dropWhileTrue 1)
--, benchPureSink "dropWhileM-true" (Ops.dropWhileMTrue 1)
, benchPureSink "dropWhile-false" (Ops.dropWhileFalse 1)
, benchPureSink "deleteBy" (Ops.deleteBy 1)
, benchPureSink "insertBy" (Ops.insertBy 1)
]
, bgroup "filteringX4"
[ benchPureSink "filter-even" (Ops.filterEven 4)
, benchPureSink "filter-all-out" (Ops.filterAllOut 4)
, benchPureSink "filter-all-in" (Ops.filterAllIn 4)
, benchPureSink "take-all" (Ops.takeAll 4)
, benchPureSink "takeWhile-true" (Ops.takeWhileTrue 4)
--, benchPureSink "takeWhileM-true" (Ops.takeWhileMTrue 4)
, benchPureSink "drop-one" (Ops.dropOne 4)
, benchPureSink "drop-all" (Ops.dropAll 4)
, benchPureSink "dropWhile-true" (Ops.dropWhileTrue 4)
--, benchPureSink "dropWhileM-true" (Ops.dropWhileMTrue 4)
, benchPureSink "dropWhile-false" (Ops.dropWhileFalse 4)
, benchPureSink "deleteBy" (Ops.deleteBy 4)
, benchPureSink "insertBy" (Ops.insertBy 4)
]
, bgroup "multi-stream"
[ benchPureSink "eqBy" Ops.eqBy
, benchPureSink "cmpBy" Ops.cmpBy
, benchPureSink "zip" Ops.zip
, benchPureSink "zipM" Ops.zipM
, benchPureSink "mergeBy" Ops.mergeBy
, benchPureSink "isPrefixOf" Ops.isPrefixOf
, benchPureSink "isSubsequenceOf" Ops.isSubsequenceOf
, benchPureSink "stripPrefix" Ops.stripPrefix
, benchPureSrc serially "concatMap" Ops.concatMap
]
-- 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"
[ benchPureSink "scanl-map" (Ops.scanMap 1)
, benchPureSink "foldl-map" Ops.foldl'ReduceMap
, benchPureSink "sum-product-fold" Ops.sumProductFold
, benchPureSink "sum-product-scan" Ops.sumProductScan
]
, bgroup "mixedX4"
[ benchPureSink "scan-map" (Ops.scanMap 4)
, benchPureSink "drop-map" (Ops.dropMap 4)
, benchPureSink "drop-scan" (Ops.dropScan 4)
, benchPureSink "take-drop" (Ops.takeDrop 4)
, benchPureSink "take-scan" (Ops.takeScan 4)
, benchPureSink "take-map" (Ops.takeMap 4)
, benchPureSink "filter-drop" (Ops.filterDrop 4)
, benchPureSink "filter-take" (Ops.filterTake 4)
, benchPureSink "filter-scan" (Ops.filterScan 4)
, benchPureSink "filter-scanl1" (Ops.filterScanl1 4)
, benchPureSink "filter-map" (Ops.filterMap 4)
]
, bgroup "iterated"
[ benchPureSrc serially "mapM" Ops.iterateMapM
, benchPureSrc serially "scan(1/100)" Ops.iterateScan
, benchPureSrc serially "scanl1(1/100)" Ops.iterateScanl1
, benchPureSrc serially "filterEven" Ops.iterateFilterEven
, benchPureSrc serially "takeAll" Ops.iterateTakeAll
, benchPureSrc serially "dropOne" Ops.iterateDropOne
, benchPureSrc serially "dropWhileFalse" Ops.iterateDropWhileFalse
, benchPureSrc serially "dropWhileTrue" Ops.iterateDropWhileTrue
]
-}
]
]