on 8ec2ebe help sign in
streamly/benchmark/LinearAsync.hs
137 lines 6.2 kB history raw
1{-# LANGUAGE CPP #-}
2-- |
3-- Module : Main
4-- Copyright : (c) 2018 Harendra Kumar
5--
6-- License : BSD3
7-- Maintainer : streamly@composewell.com
9import Control.DeepSeq (NFData)
10-- import Data.Functor.Identity (Identity, runIdentity)
11import System.Random (randomRIO)
13import Common (parseCLIOpts)
15import Streamly
16import Gauge
18import qualified Streamly.Benchmark.Prelude as Ops
20-- We need a monadic bind here to make sure that the function f does not get
21-- completely optimized out by the compiler in some cases.
22--
23-- | Takes a fold method, and uses it with a default source.
24{-# INLINE benchIO #-}
25benchIO :: (IsStream t, NFData b) => Int -> String -> (t IO Int -> IO b) -> Benchmark
26benchIO value name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source value
28-- | Takes a source, and uses it with a default drain/fold method.
29{-# INLINE benchSrcIO #-}
30benchSrcIO
31 :: (t IO Int -> SerialT IO Int)
32 -> String
33 -> (Int -> t IO Int)
34 -> Benchmark
35benchSrcIO t name f
36 = bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
38{-# INLINE benchMonadicSrcIO #-}
39benchMonadicSrcIO :: String -> (Int -> IO ()) -> Benchmark
40benchMonadicSrcIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
42{-
43_benchId :: NFData b => String -> (Ops.Stream m Int -> Identity b) -> Benchmark
44_benchId name f = bench name $ nf (runIdentity . f) (Ops.source 10)
45-}
47defaultStreamSize :: Int
48defaultStreamSize = 10000
50main :: IO ()
51main = do
52 -- XXX Fix indentation
53 (value, cfg, benches) <- parseCLIOpts defaultStreamSize
54 runMode (mode cfg) cfg benches
55 [ bgroup "asyncly"
56 [ benchSrcIO asyncly "unfoldr" (Ops.sourceUnfoldr value)
57 , benchSrcIO asyncly "unfoldrM" (Ops.sourceUnfoldrM value)
58 , benchSrcIO asyncly "fromFoldable" (Ops.sourceFromFoldable value)
59 , benchSrcIO asyncly "fromFoldableM" (Ops.sourceFromFoldableM value)
60 , benchSrcIO asyncly "foldMapWith" (Ops.sourceFoldMapWith value)
61 , benchSrcIO asyncly "foldMapWithM" (Ops.sourceFoldMapWithM value)
62 , benchSrcIO asyncly "foldMapM" (Ops.sourceFoldMapM value)
63 , benchIO value "map" $ Ops.map' asyncly 1
64 , benchIO value "fmap" $ Ops.fmap' asyncly 1
65 , benchIO value "mapM" $ Ops.mapM asyncly 1
66 , benchSrcIO asyncly "unfoldrM maxThreads 1"
67 (maxThreads 1 . Ops.sourceUnfoldrM value)
68 , benchSrcIO asyncly "unfoldrM maxBuffer 1 (x/10 ops)"
69 (maxBuffer 1 . Ops.sourceUnfoldrMN (value `div` 10))
70 , benchMonadicSrcIO "concatMapWith (2,x/2)"
71 (Ops.concatStreamsWith async 2 (value `div` 2))
72 , benchMonadicSrcIO "concatMapWith (x/2,2)"
73 (Ops.concatStreamsWith async (value `div` 2) 2)
74 ]
75 , bgroup "wAsyncly"
76 [ benchSrcIO wAsyncly "unfoldr" (Ops.sourceUnfoldr value)
77 , benchSrcIO wAsyncly "unfoldrM" (Ops.sourceUnfoldrM value)
78 , benchSrcIO wAsyncly "fromFoldable" (Ops.sourceFromFoldable value)
79 , benchSrcIO wAsyncly "fromFoldableM" (Ops.sourceFromFoldableM value)
80 , benchSrcIO wAsyncly "foldMapWith" (Ops.sourceFoldMapWith value)
81 , benchSrcIO wAsyncly "foldMapWithM" (Ops.sourceFoldMapWithM value)
82 , benchSrcIO wAsyncly "foldMapM" (Ops.sourceFoldMapM value)
83 , benchIO value "map" $ Ops.map' wAsyncly 1
84 , benchIO value "fmap" $ Ops.fmap' wAsyncly 1
85 , benchIO value "mapM" $ Ops.mapM wAsyncly 1
86 , benchMonadicSrcIO "concatMapWith (2,x/2)"
87 (Ops.concatStreamsWith wAsync 2 (value `div` 2))
88 , benchMonadicSrcIO "concatMapWith (x/2,2)"
89 (Ops.concatStreamsWith wAsync (value `div` 2) 2)
90 ]
91 -- unfoldr and fromFoldable are always serial and thereofore the same for
92 -- all stream types.
93 , bgroup "aheadly"
94 [ benchSrcIO aheadly "unfoldr" (Ops.sourceUnfoldr value)
95 , benchSrcIO aheadly "unfoldrM" (Ops.sourceUnfoldrM value)
96 , benchSrcIO aheadly "fromFoldableM" (Ops.sourceFromFoldableM value)
97 -- , benchSrcIO aheadly "foldMapWith" Ops.sourceFoldMapWith
98 , benchSrcIO aheadly "foldMapWithM" (Ops.sourceFoldMapWithM value)
99 , benchSrcIO aheadly "foldMapM" (Ops.sourceFoldMapM value)
100 , benchIO value "map" $ Ops.map' aheadly 1
101 , benchIO value "fmap" $ Ops.fmap' aheadly 1
102 , benchIO value "mapM" $ Ops.mapM aheadly 1
103 , benchSrcIO aheadly "unfoldrM maxThreads 1"
104 (maxThreads 1 . Ops.sourceUnfoldrM value)
105 , benchSrcIO aheadly "unfoldrM maxBuffer 1 (x/10 ops)"
106 (maxBuffer 1 . Ops.sourceUnfoldrMN (value `div` 10))
107 -- , benchSrcIO aheadly "fromFoldable" Ops.sourceFromFoldable
108 , benchMonadicSrcIO "concatMapWith (2,x/2)"
109 (Ops.concatStreamsWith ahead 2 (value `div` 2))
110 , benchMonadicSrcIO "concatMapWith (x/2,2)"
111 (Ops.concatStreamsWith ahead (value `div` 2) 2)
112 ]
113 -- XXX need to use smaller streams to finish in reasonable time
114 , bgroup "parallely"
115 [ benchSrcIO parallely "unfoldr" (Ops.sourceUnfoldr value)
116 , benchSrcIO parallely "unfoldrM" (Ops.sourceUnfoldrM value)
117 --, benchSrcIO parallely "fromFoldable" Ops.sourceFromFoldable
118 , benchSrcIO parallely "fromFoldableM" (Ops.sourceFromFoldableM value)
119 -- , benchSrcIO parallely "foldMapWith" Ops.sourceFoldMapWith
120 , benchSrcIO parallely "foldMapWithM" (Ops.sourceFoldMapWithM value)
121 , benchSrcIO parallely "foldMapM" (Ops.sourceFoldMapM value)
122 , benchIO value "map" $ Ops.map' parallely 1
123 , benchIO value "fmap" $ Ops.fmap' parallely 1
124 , benchIO value "mapM" $ Ops.mapM parallely 1
125 -- Zip has only one parallel flavor
126 , benchIO value "zip" Ops.zipAsync
127 , benchIO value "zipM" Ops.zipAsyncM
128 , benchIO value "zipAp" Ops.zipAsyncAp
129 -- Parallel stages in a pipeline
130 , benchIO value "parAppMap" Ops.parAppMap
131 , benchIO value "parAppSum" Ops.parAppSum
132 , benchMonadicSrcIO "concatMapWith (2,x/2)"
133 (Ops.concatStreamsWith parallel 2 (value `div` 2))
134 , benchMonadicSrcIO "concatMapWith (x/10,10)"
135 (Ops.concatStreamsWith parallel (value `div` 10) 10)
136 ]
137 ]