on master help sign in
add linear-async, base streams benchmark reporting
a929a16Harendra Kumar
bench.sh+14−27
@@ -39,8 +39,7 @@ set_benchmarks() {
39
39
40# $1: benchmark name (linear, nested, base)
40# $1: benchmark name (linear, nested, base)
41find_report_prog() {
41find_report_prog() {
42− local bench_name=$1
43− local prog_name="chart-$bench_name"
42+ local prog_name="chart"
44 hash -r
43 hash -r
45 local prog_path=$($STACK exec which $prog_name)
44 local prog_path=$($STACK exec which $prog_name)
46 if test -x "$prog_path"
45 if test -x "$prog_path"
@@ -53,8 +52,7 @@ find_report_prog() {
53
52
54# $1: benchmark name (linear, nested, base)
53# $1: benchmark name (linear, nested, base)
55build_report_prog() {
54build_report_prog() {
56− local bench_name=$1
57− local prog_name="chart-$bench_name"
55+ local prog_name="chart"
58 local prog_path=$($STACK exec which $prog_name)
56 local prog_path=$($STACK exec which $prog_name)
59
57
60 hash -r
58 hash -r
@@ -71,18 +69,13 @@ build_report_prog() {
71}
69}
72
70
73build_report_progs() {
71build_report_progs() {
74− local bench_list=$1
75−
76 if test "$RAW" = "0"
72 if test "$RAW" = "0"
77 then
73 then
78− for i in $bench_list
79− do
80− build_report_prog $i || exit 1
74+ build_report_prog || exit 1
81 local prog
75 local prog
82− prog=$(find_report_prog $i) || \
76+ prog=$(find_report_prog) || \
83− die "Cannot find bench-graph executable for benchmark $i"
77+ die "Cannot find bench-graph executable"
84 echo "Using bench-graph executable [$prog]"
78 echo "Using bench-graph executable [$prog]"
85− done
86 fi
79 fi
87}
80}
88
81
@@ -198,25 +191,16 @@ run_measurements() {
198 fi
191 fi
199}
192}
200
193
201−run_report() {
194+run_reports() {
202− local bench_name=$1
203− local input_file=$2
204−
205− if test "$RAW" = "0"
206− then
207 local prog
195 local prog
208− prog=$(find_report_prog $bench_name) || \
196+ prog=$(find_report_prog) || \
209− die "Cannot find bench-graph executable for benchmark $bench_name"
197+ die "Cannot find bench-graph executable"
210 echo
198 echo
211− echo "Generating reports for ${bench_name}..."
212− $prog
213− fi
214−}
215
199
216−run_reports() {
217 for i in $1
200 for i in $1
218 do
201 do
219− run_report $i
202+ echo "Generating reports for ${i}..."
203+ $prog --benchmark $i
220 done
204 done
221}
205}
222
206
@@ -290,4 +274,7 @@ fi
290# Run reports
274# Run reports
291#-----------------------------------------------------------------------------
275#-----------------------------------------------------------------------------
292
276
277+if test "$RAW" = "0"
278+then
293−run_reports "$BENCHMARKS"
279+ run_reports "$BENCHMARKS"
280+fi
benchmark/Chart.hsnew file+187
@@ -0,0 +1,187 @@
1+{-# LANGUAGE TupleSections #-}
2+{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE ScopedTypeVariables #-}
4+
5+module Main where
6+
7+import Control.Exception (handle, catch, SomeException, ErrorCall(..))
8+import Control.Monad.Trans.State
9+import Control.Monad.Trans.Maybe
10+import Data.List
11+import Data.List.Split
12+import Data.Ord (comparing)
13+import System.Environment (getArgs)
14+import Control.Monad.IO.Class (liftIO)
15+import Control.Monad (mzero)
16+
17+import BenchGraph
18+
19+------------------------------------------------------------------------------
20+-- Command line parsing
21+------------------------------------------------------------------------------
22+
23+data BenchType = Linear | LinearAsync | Nested | Base
24+
25+data Options = Options
26+ { genGraphs :: Bool
27+ , benchType :: BenchType
28+ }
29+
30+defaultOptions = Options False Linear
31+
32+setGenGraphs val = do
33+ (args, opts) <- get
34+ put (args, opts { genGraphs = val })
35+
36+setBenchType val = do
37+ (args, opts) <- get
38+ put (args, opts { benchType = val })
39+
40+-- Like the shell "shift" to shift the command line arguments
41+shift :: StateT ([String], Options) (MaybeT IO) (Maybe String)
42+shift = do
43+ s <- get
44+ case s of
45+ ([], _) -> return Nothing
46+ (x : xs, opts) -> put (xs, opts) >> return (Just x)
47+
48+parseBench :: StateT ([String], Options) (MaybeT IO) ()
49+parseBench = do
50+ x <- shift
51+ case x of
52+ Just "linear" -> setBenchType Linear
53+ Just "linear-async" -> setBenchType LinearAsync
54+ Just "nested" -> setBenchType Nested
55+ Just "base" -> setBenchType Base
56+ Just str -> do
57+ liftIO $ putStrLn $ "unrecognized benchmark type " ++ str
58+ mzero
59+ Nothing -> do
60+ liftIO $ putStrLn $ "please provide a benchmark type "
61+ mzero
62+
63+-- totally imperative style option parsing
64+parseOptions :: IO (Maybe Options)
65+parseOptions = do
66+ args <- getArgs
67+ runMaybeT $ flip evalStateT (args, defaultOptions) $ do
68+ x <- shift
69+ case x of
70+ Just "--graphs" -> setGenGraphs True
71+ Just "--benchmark" -> parseBench
72+ Just str -> do
73+ liftIO $ putStrLn $ "Unrecognized option " ++ str
74+ mzero
75+ Nothing -> return ()
76+ fmap snd get
77+
78+ignoringErr a = catch a (\(ErrorCall err :: ErrorCall) ->
79+ putStrLn $ "Failed with error:\n" ++ err ++ "\nSkipping.")
80+
81+------------------------------------------------------------------------------
82+-- Linear composition charts
83+------------------------------------------------------------------------------
84+
85+makeLinearGraphs :: Config -> String -> IO ()
86+makeLinearGraphs cfg inputFile = do
87+ ignoringErr $ graph inputFile "operations" $ cfg
88+ { title = Just "Streamly operations"
89+ , classifyBenchmark = \b ->
90+ if (not $ "serially/" `isPrefixOf` b)
91+ || "/generation" `isInfixOf` b
92+ || "/compose" `isInfixOf` b
93+ || "/concat" `isSuffixOf` b
94+ then Nothing
95+ else Just ("Streamly", last $ splitOn "/" b)
96+ }
97+
98+ ignoringErr $ graph inputFile "generation" $ cfg
99+ { title = Just "Stream generation"
100+ , classifyBenchmark = \b ->
101+ if "serially/generation" `isPrefixOf` b
102+ then Just ("Streamly", last $ splitOn "/" b)
103+ else Nothing
104+ }
105+
106+ ignoringErr $ graph inputFile "composition" $ cfg
107+ { title = Just "Streamly composition performance"
108+ , classifyBenchmark = fmap ("Streamly",) . stripPrefix "serially/compose/"
109+ }
110+
111+ ignoringErr $ graph inputFile "composition-scaling"
112+ $ cfg
113+ { title = Just "Streamly composition scaling"
114+ , classifyBenchmark = fmap ("Streamly",) . stripPrefix "serially/compose-"
115+ }
116+
117+------------------------------------------------------------------------------
118+-- Nested composition charts
119+------------------------------------------------------------------------------
120+
121+makeNestedGraphs :: Config -> String -> IO ()
122+makeNestedGraphs cfg inputFile = do
123+ ignoringErr $ graph inputFile "nested-serial-diff" $ cfg
124+ { title = Just "Nested serial"
125+ , classifyBenchmark = \b ->
126+ let ls = splitOn "/" b
127+ in case head ls of
128+ "serially" -> Just (head ls, last ls)
129+ _ -> Nothing
130+ }
131+
132+------------------------------------------------------------------------------
133+-- Charts for parallel streams
134+------------------------------------------------------------------------------
135+
136+makeLinearAsyncGraphs :: Config -> String -> IO ()
137+makeLinearAsyncGraphs cfg inputFile = do
138+ putStrLn "Not implemented"
139+ return ()
140+
141+------------------------------------------------------------------------------
142+-- Charts for base streams
143+------------------------------------------------------------------------------
144+
145+makeBaseGraphs :: Config -> String -> IO ()
146+makeBaseGraphs cfg inputFile = do
147+ putStrLn "Not implemented"
148+ return ()
149+
150+------------------------------------------------------------------------------
151+-- text reports
152+------------------------------------------------------------------------------
153+
154+benchShow Options{..} cfg func inp out =
155+ if genGraphs
156+ then func cfg {outputDir = Just out} inp
157+ else
158+ ignoringErr $ report inp Nothing $ cfg
159+ { selectBenchmarks =
160+ \f ->
161+ reverse $ map fst $
162+ sortBy (comparing snd) $ f $ ColumnIndex 1
163+ }
164+
165+main :: IO ()
166+main = do
167+ let cfg = defaultConfig { presentation = Groups PercentDiff }
168+ res <- parseOptions
169+
170+ case res of
171+ Nothing -> do
172+ putStrLn "cannot parse options"
173+ return ()
174+ Just opts@Options{..} -> do
175+ case benchType of
176+ Linear -> benchShow opts cfg makeLinearGraphs
177+ "charts/linear/results.csv"
178+ "charts/linear"
179+ LinearAsync -> benchShow opts cfg makeLinearAsyncGraphs
180+ "charts/linear-async/results.csv"
181+ "charts/linear-async"
182+ Nested -> benchShow opts cfg makeNestedGraphs
183+ "charts/nested/results.csv"
184+ "charts/nested"
185+ Base -> benchShow opts cfg makeBaseGraphs
186+ "charts/base/results.csv"
187+ "charts/base"
benchmark/ChartLinear.hsdeleted−90
@@ -1,90 +0,0 @@
1−{-# LANGUAGE TupleSections #-}
2−{-# LANGUAGE RecordWildCards #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−
5−module Main where
6−
7−import Control.Exception (handle, catch, SomeException, ErrorCall(..))
8−import Control.Monad.Trans.State
9−import Control.Monad.Trans.Maybe
10−import Data.List
11−import Data.List.Split
12−import Data.Ord (comparing)
13−import System.Environment (getArgs)
14−import Control.Monad.IO.Class (liftIO)
15−import Control.Monad (mzero)
16−
17−import BenchGraph
18−import Utils
19−
20−ignoringErr a = catch a (\(ErrorCall err :: ErrorCall) ->
21− putStrLn $ "Failed with error:\n" ++ err ++ "\nSkipping.")
22−
23−makeGraphs cfg = do
24− ignoringErr $ graph inputFile "operations" $ cfg
25− { title = Just "Streamly operations"
26− , classifyBenchmark = \b ->
27− if (not $ "serially/" `isPrefixOf` b)
28− || "/generation" `isInfixOf` b
29− || "/compose" `isInfixOf` b
30− || "/concat" `isSuffixOf` b
31− then Nothing
32− else Just ("Streamly", last $ splitOn "/" b)
33− }
34−
35− ignoringErr $ graph inputFile "generation" $ cfg
36− { title = Just "Stream generation"
37− , classifyBenchmark = \b ->
38− if "serially/generation" `isPrefixOf` b
39− then Just ("Streamly", last $ splitOn "/" b)
40− else Nothing
41− }
42−
43− ignoringErr $ graph inputFile "composition" $ cfg
44− { title = Just "Streamly composition performance"
45− , classifyBenchmark = fmap ("Streamly",) . stripPrefix "serially/compose/"
46− }
47−
48− ignoringErr $ graph inputFile "composition-scaling"
49− $ cfg
50− { title = Just "Streamly composition scaling"
51− , classifyBenchmark = fmap ("Streamly",) . stripPrefix "serially/compose-"
52− }
53−
54−inputFile :: String
55−inputFile = "charts/linear/results.csv"
56−
57−-- Primitive command line options parsing
58−data Options = Options
59− { genGraphs :: Bool
60− }
61−
62−main :: IO ()
63−main = do
64− let cfg = defaultConfig
65− { outputDir = Just "charts/linear"
66− , presentation = Groups PercentDiff
67− }
68−
69− args <- getArgs
70− res <- runMaybeT $ flip evalStateT args $ do
71− x <- shift
72− case x of
73− Just "--graphs" -> return $ Options { genGraphs = True }
74− Nothing -> return $ Options { genGraphs = False }
75− Just str -> do
76− liftIO $ putStrLn $ "Unrecognized option " ++ str
77− mzero
78−
79− case res of
80− Nothing -> return ()
81− Just Options{..} ->
82− if genGraphs
83− then makeGraphs cfg
84− else
85− ignoringErr $ report inputFile Nothing $ cfg
86− { selectBenchmarks =
87− \f ->
88− reverse $ map fst $
89− sortBy (comparing snd) $ f $ ColumnIndex 1
90− }
benchmark/ChartNested.hsdeleted−70
@@ -1,70 +0,0 @@
1−{-# LANGUAGE TupleSections #-}
2−{-# LANGUAGE RecordWildCards #-}
3−{-# LANGUAGE ScopedTypeVariables #-}
4−
5−module Main where
6−
7−import Control.Exception (handle, catch, SomeException, ErrorCall)
8−import Control.Monad.Trans.State
9−import Control.Monad.Trans.Maybe
10−import Data.List
11−import Data.List.Split
12−import Data.Ord (comparing)
13−import System.Environment (getArgs)
14−import Control.Monad.IO.Class (liftIO)
15−import Control.Monad (mzero)
16−
17−import BenchGraph
18−import Utils
19−
20−ignoringErr a = catch a (\(_ :: ErrorCall) ->
21− putStrLn "Failed. Skipping.")
22−
23−makeGraphs :: Config -> IO ()
24−makeGraphs cfg = do
25− ignoringErr $ graph inputFile "nested-serial-diff" $ cfg
26− { title = Just "Nested serial"
27− , classifyBenchmark = \b ->
28− let ls = splitOn "/" b
29− in case head ls of
30− "serially" -> Just (head ls, last ls)
31− _ -> Nothing
32− }
33−
34−-- Primitive command line options parsing
35−data Options = Options
36− { genGraphs :: Bool
37− }
38−
39−inputFile :: String
40−inputFile = "charts/nested/results.csv"
41−
42−main :: IO ()
43−main = do
44− let cfg = defaultConfig
45− { outputDir = Just "charts/nested"
46− , presentation = Groups PercentDiff
47− }
48−
49− args <- getArgs
50− res <- runMaybeT $ flip evalStateT args $ do
51− x <- shift
52− case x of
53− Just "--graphs" -> return $ Options { genGraphs = True }
54− Nothing -> return $ Options { genGraphs = False }
55− Just str -> do
56− liftIO $ putStrLn $ "Unrecognized option " ++ str
57− mzero
58−
59− case res of
60− Nothing -> return ()
61− Just Options{..} ->
62− if genGraphs
63− then makeGraphs cfg
64− else
65− ignoringErr $ report inputFile Nothing $ cfg
66− { selectBenchmarks =
67− \f ->
68− reverse $ map fst $
69− sortBy (comparing snd) $ f $ ColumnIndex 1
70− }
benchmark/Linear.hs+2−75
@@ -19,7 +19,7 @@ import Gauge
19-- | Takes a fold method, and uses it with a default source.
19-- | Takes a fold method, and uses it with a default source.
20{-# INLINE benchIO #-}
20{-# INLINE benchIO #-}
21benchIO :: (IsStream t, NFData b) => String -> (t IO Int -> IO b) -> Benchmark
21benchIO :: (IsStream t, NFData b) => String -> (t IO Int -> IO b) -> Benchmark
22−benchIO name f = bench name $ nfIO $ randomRIO (1,1000) >>= f . Ops.source
22+benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source
23
23
24-- | Takes a source, and uses it with a default drain/fold method.
24-- | Takes a source, and uses it with a default drain/fold method.
25{-# INLINE benchSrcIO #-}
25{-# INLINE benchSrcIO #-}
@@ -29,7 +29,7 @@ benchSrcIO
29 -> (Int -> t IO Int)
29 -> (Int -> t IO Int)
30 -> Benchmark
30 -> Benchmark
31benchSrcIO t name f
31benchSrcIO t name f
32− = bench name $ nfIO $ randomRIO (1,1000) >>= Ops.toNull t . f
32+ = bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
33
33
34{-
34{-
35_benchId :: NFData b => String -> (Ops.Stream m Int -> Identity b) -> Benchmark
35_benchId :: NFData b => String -> (Ops.Stream m Int -> Identity b) -> Benchmark
@@ -123,77 +123,4 @@ main = do
123 , benchIO "4" $ Ops.composeScaling 4
123 , benchIO "4" $ Ops.composeScaling 4
124 ]
124 ]
125 ]
125 ]
126− , bgroup "asyncly"
127− [ -- benchIO "unfoldr" $ Ops.toNull asyncly
128− benchSrcIO asyncly "unfoldrM" Ops.sourceUnfoldrM
129− -- , benchSrcIO asyncly "fromFoldable" Ops.sourceFromFoldable
130− , benchSrcIO asyncly "fromFoldableM" Ops.sourceFromFoldableM
131− -- , benchSrcIO asyncly "foldMapWith" Ops.sourceFoldMapWith
132− , benchSrcIO asyncly "foldMapWithM" Ops.sourceFoldMapWithM
133− , benchIO "mapM" $ Ops.mapM asyncly
134− , benchSrcIO asyncly "unfoldrM maxThreads 1"
135− (maxThreads 1 . Ops.sourceUnfoldrM)
136− , benchSrcIO asyncly "unfoldrM maxBuffer 1 (1000 ops)"
137− (maxBuffer 1 . Ops.sourceUnfoldrMN 1000)
138− ]
139− , bgroup "asyncly/rate"
140− [ -- benchIO "unfoldr" $ Ops.toNull asyncly
141− benchSrcIO asyncly "unfoldrM" Ops.sourceUnfoldrM
142− , benchSrcIO asyncly "unfoldrM/Nothing"
143− (rate Nothing . Ops.sourceUnfoldrM)
144− , benchSrcIO asyncly "unfoldrM/AvgRate/1,000,000"
145− (avgRate 1000000 . Ops.sourceUnfoldrM)
146− , benchSrcIO asyncly "unfoldrM/AvgRate/3,000,000"
147− (avgRate 3000000 . Ops.sourceUnfoldrM)
148− , benchSrcIO asyncly "unfoldrM/AvgRate/10,000,000/maxThreads1"
149− (maxThreads 1 . avgRate 10000000 . Ops.sourceUnfoldrM)
150− -- XXX arbitrarily large rate should be the same as rate Nothing
151− , benchSrcIO asyncly "unfoldrM/AvgRate/10,000,000"
152− (avgRate 10000000 . Ops.sourceUnfoldrM)
153− , benchSrcIO asyncly "unfoldrM/AvgRate/20,000,000"
154− (avgRate 20000000 . Ops.sourceUnfoldrM)
155− ]
156− , bgroup "wAsyncly"
157− [ -- benchIO "unfoldr" $ Ops.toNull wAsyncly
158− benchSrcIO wAsyncly "unfoldrM" Ops.sourceUnfoldrM
159− -- , benchSrcIO wAsyncly "fromFoldable" Ops.sourceFromFoldable
160− , benchSrcIO wAsyncly "fromFoldableM" Ops.sourceFromFoldableM
161− -- , benchSrcIO wAsyncly "foldMapWith" Ops.sourceFoldMapWith
162− , benchSrcIO wAsyncly "foldMapWithM" Ops.sourceFoldMapWithM
163− , benchIO "mapM" $ Ops.mapM wAsyncly
164− ]
165− -- unfoldr and fromFoldable are always serial and thereofore the same for
166− -- all stream types.
167− , bgroup "aheadly"
168− [ -- benchIO "unfoldr" $ Ops.toNull aheadly
169− benchSrcIO aheadly "unfoldrM" Ops.sourceUnfoldrM
170− , benchSrcIO aheadly "fromFoldableM" Ops.sourceFromFoldableM
171− -- , benchSrcIO aheadly "foldMapWith" Ops.sourceFoldMapWith
172− , benchSrcIO aheadly "foldMapWithM" Ops.sourceFoldMapWithM
173− , benchIO "mapM" $ Ops.mapM aheadly
174− , benchSrcIO aheadly "unfoldrM maxThreads 1"
175− (maxThreads 1 . Ops.sourceUnfoldrM)
176− , benchSrcIO aheadly "unfoldrM maxBuffer 1 (1000 ops)"
177− (maxBuffer 1 . Ops.sourceUnfoldrMN 1000)
178− -- , benchSrcIO aheadly "fromFoldable" Ops.sourceFromFoldable
179− ]
180− , bgroup "aheadly/rate"
181− [
182− -- XXX arbitrarily large maxRate should be the same as maxRate -1
183− benchSrcIO aheadly "unfoldrM rate AvgRate 1000000"
184− (avgRate 1000000 . Ops.sourceUnfoldrM)
185− ]
186− -- XXX need to use smaller streams to finish in reasonable time
187− , bgroup "parallely"
188− [ --benchIO "unfoldr" $ Ops.toNull parallely
189− benchSrcIO parallely "unfoldrM" Ops.sourceUnfoldrM
190− --, benchSrcIO parallely "fromFoldable" Ops.sourceFromFoldable
191− , benchSrcIO parallely "fromFoldableM" Ops.sourceFromFoldableM
192− -- , benchSrcIO parallely "foldMapWith" Ops.sourceFoldMapWith
193− , benchSrcIO parallely "foldMapWithM" Ops.sourceFoldMapWithM
194− , benchIO "mapM" $ Ops.mapM parallely
195− -- Zip has only one parallel flavor
196− , benchIO "zip" $ Ops.zipAsync
197− , benchIO "zipM" $ Ops.zipAsyncM
198− ]
199 ]
126 ]
benchmark/LinearAsync.hsnew file+115
@@ -0,0 +1,115 @@
1+-- |
2+-- Module : Main
3+-- Copyright : (c) 2018 Harendra Kumar
4+--
5+-- License : BSD3
6+-- Maintainer : harendra.kumar@gmail.com
7+
8+import Control.DeepSeq (NFData)
9+-- import Data.Functor.Identity (Identity, runIdentity)
10+import System.Random (randomRIO)
11+import qualified LinearOps as Ops
12+
13+import Streamly
14+import Gauge
15+
16+-- We need a monadic bind here to make sure that the function f does not get
17+-- completely optimized out by the compiler in some cases.
18+--
19+-- | Takes a fold method, and uses it with a default source.
20+{-# INLINE benchIO #-}
21+benchIO :: (IsStream t, NFData b) => String -> (t IO Int -> IO b) -> Benchmark
22+benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source
23+
24+-- | Takes a source, and uses it with a default drain/fold method.
25+{-# INLINE benchSrcIO #-}
26+benchSrcIO
27+ :: (t IO Int -> SerialT IO Int)
28+ -> String
29+ -> (Int -> t IO Int)
30+ -> Benchmark
31+benchSrcIO t name f
32+ = bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
33+
34+{-
35+_benchId :: NFData b => String -> (Ops.Stream m Int -> Identity b) -> Benchmark
36+_benchId name f = bench name $ nf (runIdentity . f) (Ops.source 10)
37+-}
38+
39+main :: IO ()
40+main = do
41+ defaultMain
42+ [ bgroup "asyncly"
43+ [ -- benchIO "unfoldr" $ Ops.toNull asyncly
44+ benchSrcIO asyncly "unfoldrM" Ops.sourceUnfoldrM
45+ -- , benchSrcIO asyncly "fromFoldable" Ops.sourceFromFoldable
46+ , benchSrcIO asyncly "fromFoldableM" Ops.sourceFromFoldableM
47+ -- , benchSrcIO asyncly "foldMapWith" Ops.sourceFoldMapWith
48+ , benchSrcIO asyncly "foldMapWithM" Ops.sourceFoldMapWithM
49+ , benchIO "mapM" $ Ops.mapM asyncly
50+ , benchSrcIO asyncly "unfoldrM maxThreads 1"
51+ (maxThreads 1 . Ops.sourceUnfoldrM)
52+ , benchSrcIO asyncly "unfoldrM maxBuffer 1 (1000 ops)"
53+ (maxBuffer 1 . Ops.sourceUnfoldrMN 1000)
54+ ]
55+ , bgroup "asyncly/rate"
56+ [ -- benchIO "unfoldr" $ Ops.toNull asyncly
57+ benchSrcIO asyncly "unfoldrM" Ops.sourceUnfoldrM
58+ , benchSrcIO asyncly "unfoldrM/Nothing"
59+ (rate Nothing . Ops.sourceUnfoldrM)
60+ , benchSrcIO asyncly "unfoldrM/AvgRate/1,000,000"
61+ (avgRate 1000000 . Ops.sourceUnfoldrM)
62+ , benchSrcIO asyncly "unfoldrM/AvgRate/3,000,000"
63+ (avgRate 3000000 . Ops.sourceUnfoldrM)
64+ , benchSrcIO asyncly "unfoldrM/AvgRate/10,000,000/maxThreads1"
65+ (maxThreads 1 . avgRate 10000000 . Ops.sourceUnfoldrM)
66+ -- XXX arbitrarily large rate should be the same as rate Nothing
67+ , benchSrcIO asyncly "unfoldrM/AvgRate/10,000,000"
68+ (avgRate 10000000 . Ops.sourceUnfoldrM)
69+ , benchSrcIO asyncly "unfoldrM/AvgRate/20,000,000"
70+ (avgRate 20000000 . Ops.sourceUnfoldrM)
71+ ]
72+ , bgroup "wAsyncly"
73+ [ -- benchIO "unfoldr" $ Ops.toNull wAsyncly
74+ benchSrcIO wAsyncly "unfoldrM" Ops.sourceUnfoldrM
75+ -- , benchSrcIO wAsyncly "fromFoldable" Ops.sourceFromFoldable
76+ , benchSrcIO wAsyncly "fromFoldableM" Ops.sourceFromFoldableM
77+ -- , benchSrcIO wAsyncly "foldMapWith" Ops.sourceFoldMapWith
78+ , benchSrcIO wAsyncly "foldMapWithM" Ops.sourceFoldMapWithM
79+ , benchIO "mapM" $ Ops.mapM wAsyncly
80+ ]
81+ -- unfoldr and fromFoldable are always serial and thereofore the same for
82+ -- all stream types.
83+ , bgroup "aheadly"
84+ [ -- benchIO "unfoldr" $ Ops.toNull aheadly
85+ benchSrcIO aheadly "unfoldrM" Ops.sourceUnfoldrM
86+ , benchSrcIO aheadly "fromFoldableM" Ops.sourceFromFoldableM
87+ -- , benchSrcIO aheadly "foldMapWith" Ops.sourceFoldMapWith
88+ , benchSrcIO aheadly "foldMapWithM" Ops.sourceFoldMapWithM
89+ , benchIO "mapM" $ Ops.mapM aheadly
90+ , benchSrcIO aheadly "unfoldrM maxThreads 1"
91+ (maxThreads 1 . Ops.sourceUnfoldrM)
92+ , benchSrcIO aheadly "unfoldrM maxBuffer 1 (1000 ops)"
93+ (maxBuffer 1 . Ops.sourceUnfoldrMN 1000)
94+ -- , benchSrcIO aheadly "fromFoldable" Ops.sourceFromFoldable
95+ ]
96+ , bgroup "aheadly/rate"
97+ [
98+ -- XXX arbitrarily large maxRate should be the same as maxRate -1
99+ benchSrcIO aheadly "unfoldrM rate AvgRate 1000000"
100+ (avgRate 1000000 . Ops.sourceUnfoldrM)
101+ ]
102+ -- XXX need to use smaller streams to finish in reasonable time
103+ , bgroup "parallely"
104+ [ --benchIO "unfoldr" $ Ops.toNull parallely
105+ benchSrcIO parallely "unfoldrM" Ops.sourceUnfoldrM
106+ --, benchSrcIO parallely "fromFoldable" Ops.sourceFromFoldable
107+ , benchSrcIO parallely "fromFoldableM" Ops.sourceFromFoldableM
108+ -- , benchSrcIO parallely "foldMapWith" Ops.sourceFoldMapWith
109+ , benchSrcIO parallely "foldMapWithM" Ops.sourceFoldMapWithM
110+ , benchIO "mapM" $ Ops.mapM parallely
111+ -- Zip has only one parallel flavor
112+ , benchIO "zip" $ Ops.zipAsync
113+ , benchIO "zipM" $ Ops.zipAsyncM
114+ ]
115+ ]
benchmark/LinearOps.hs+6−1
@@ -5,6 +5,7 @@
5-- License : MIT
5-- License : MIT
6-- Maintainer : harendra.kumar@gmail.com
6-- Maintainer : harendra.kumar@gmail.com
7
7
8+{-# LANGUAGE CPP #-}
8{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE FlexibleContexts #-}
9
10
10module LinearOps where
11module LinearOps where
@@ -18,8 +19,12 @@ import qualified Streamly as S
18import qualified Streamly.Prelude as S
19import qualified Streamly.Prelude as S
19
20
20value, maxValue :: Int
21value, maxValue :: Int
22+#ifdef LINEAR_ASYNC
23+value = 10000
24+#else
21value = 100000
25value = 100000
26+#endif
22−maxValue = value + 1000
27+maxValue = value + 1
23
28
24-------------------------------------------------------------------------------
29-------------------------------------------------------------------------------
25-- Benchmark ops
30-- Benchmark ops
benchmark/Utils.hsdeleted−13
@@ -1,13 +0,0 @@
1−module Utils where
2−
3−import Control.Monad.Trans.State
4−import Control.Monad.Trans.Maybe
5−
6−-- Like the shell "shift" to shift the command line arguments
7−shift :: StateT [String] (MaybeT IO) (Maybe String)
8−shift = do
9− s <- get
10− case s of
11− [] -> return Nothing
12− x : xs -> put xs >> return (Just x)
13−
stack.yaml+2−2
@@ -10,9 +10,9 @@ extra-deps:
10 - Chart-diagrams-1.9
10 - Chart-diagrams-1.9
11 - SVGFonts-1.6.0.3
11 - SVGFonts-1.6.0.3
12 - math-functions-0.3.0.2
12 - math-functions-0.3.0.2
13− - git: git@github.com:composewell/bench-graph
13+ - git: https://github.com/composewell/bench-graph
14 commit: 27ea72037f01e252364197e4771e25478af97972
14 commit: 27ea72037f01e252364197e4771e25478af97972
15− - git: git@github.com:harendra-kumar/statistics
15+ - git: https://github.com/harendra-kumar/statistics
16 commit: d3c4743c28fdd83d578039867f1a046596f77140
16 commit: d3c4743c28fdd83d578039867f1a046596f77140
17 subdirs:
17 subdirs:
18 - dense-linear-algebra
18 - dense-linear-algebra
streamly.cabal+31−19
@@ -323,6 +323,34 @@ benchmark linear
323 , random >= 1.0 && < 2.0
323 , random >= 1.0 && < 2.0
324 , gauge >= 0.2.3 && < 0.3
324 , gauge >= 0.2.3 && < 0.3
325
325
326+benchmark linear-async
327+ type: exitcode-stdio-1.0
328+ hs-source-dirs: benchmark
329+ main-is: LinearAsync.hs
330+ other-modules: LinearOps
331+ default-language: Haskell2010
332+ ghc-options: -O2 -Wall
333+ cpp-options: -DLINEAR_ASYNC
334+ if flag(dev)
335+ ghc-options: -Wmissed-specialisations
336+ -Wall-missed-specialisations
337+ -fno-ignore-asserts
338+ if impl(ghc >= 8.0)
339+ ghc-options: -Wcompat
340+ -Wunrecognised-warning-flags
341+ -Widentities
342+ -Wincomplete-record-updates
343+ -Wincomplete-uni-patterns
344+ -Wredundant-constraints
345+ -Wnoncanonical-monad-instances
346+ -Wnoncanonical-monadfail-instances
347+ build-depends:
348+ streamly
349+ , base >= 4.8 && < 5
350+ , deepseq >= 1.4.0 && < 1.5
351+ , random >= 1.0 && < 2.0
352+ , gauge >= 0.2.3 && < 0.3
353+
326benchmark nested
354benchmark nested
327 type: exitcode-stdio-1.0
355 type: exitcode-stdio-1.0
328 hs-source-dirs: benchmark
356 hs-source-dirs: benchmark
@@ -410,31 +438,15 @@ benchmark base
410 build-depends:
438 build-depends:
411 semigroups >= 0.18 && < 0.19
439 semigroups >= 0.18 && < 0.19
412
440
413−executable chart-linear
441+executable chart
414− default-language: Haskell2010
415− hs-source-dirs: benchmark
416− main-is: ChartLinear.hs
417− other-modules: Utils
418− if flag(dev)
419− buildable: True
420− build-Depends:
421− base >= 4.8 && < 5
422− , bench-graph >= 0.1 && < 0.2
423− , split
424− , transformers
425− else
426− buildable: False
427−
428−executable chart-nested
429 default-language: Haskell2010
442 default-language: Haskell2010
430 hs-source-dirs: benchmark
443 hs-source-dirs: benchmark
431− main-is: ChartNested.hs
444+ main-is: Chart.hs
432− other-modules: Utils
433 if flag(dev)
445 if flag(dev)
434 buildable: True
446 buildable: True
435 build-Depends:
447 build-Depends:
436 base >= 4.8 && < 5
448 base >= 4.8 && < 5
437− , bench-graph >= 0.1 && < 0.2
449+ , bench-graph >= 0.2 && < 0.3
438 , split
450 , split
439 , transformers
451 , transformers
440 else
452 else