on master help sign in
Add dev benchmarks for base cont and direct streams
commit9bb5ac1ea25f3d03037e6220d91fbba23076f3dc authorHarendra Kumar <harendra.kumar@gmail.com> dateSat 23 Jun 2018, 20:57 (8 years ago) parent0b6d7a2
5 files changed+512−10
benchmark/BaseStreams.hs+96 benchmark/Linear.hs+12−9 benchmark/StreamDOps.hs+179 benchmark/StreamKOps.hs+178 streamly.cabal+47−1
benchmark/BaseStreams.hsnew file+96
@@ -0,0 +1,96 @@
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+
12+import Gauge
13+import qualified StreamDOps as D
14+import qualified StreamKOps as K
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+{-# INLINE benchIO #-}
19+benchIO :: String -> (a IO Int -> IO ()) -> (Int -> a IO Int) -> Benchmark
20+benchIO name run f = bench name $ nfIO $ randomRIO (1,1000) >>= run . f
21+
22+benchFold :: NFData b
23+ => String -> (t IO Int -> IO b) -> (Int -> t IO Int) -> Benchmark
24+benchFold name f src = bench name $ nfIO $ randomRIO (1,1000) >>= f . src
25+
26+{-
27+_benchId :: NFData b => String -> (Ops.Stream m Int -> Identity b) -> Benchmark
28+_benchId name f = bench name $ nf (runIdentity . f) (Ops.source 10)
29+-}
30+
31+main :: IO ()
32+main = do
33+ defaultMain
34+ [ bgroup "streamD"
35+ [ bgroup "generation"
36+ [ benchIO "unfoldr" D.toNull D.sourceUnfoldr
37+ , benchIO "unfoldrM" D.toNull D.sourceUnfoldrM
38+ , benchIO "fromEnum" D.toNull D.sourceFromEnum
39+
40+ , benchIO "fromFoldable" D.toNull D.sourceFromFoldable
41+ -- , benchIO "fromFoldableM" D.sourceFromFoldableM
42+ ]
43+ , bgroup "transformation"
44+ [
45+ benchIO "mapM" D.mapM D.sourceUnfoldrM
46+ ]
47+ ]
48+ , bgroup "streamK"
49+ [ bgroup "generation"
50+ [ benchIO "unfoldr" K.toNull K.sourceUnfoldr
51+ , benchIO "unfoldrM" K.toNull K.sourceUnfoldrM
52+ -- , benchIO "fromEnum" K.toNull K.sourceFromEnum
53+
54+ , benchIO "fromFoldable" K.toNull K.sourceFromFoldable
55+ , benchIO "fromFoldableM" K.toNull K.sourceFromFoldableM
56+
57+ -- appends
58+ , benchIO "foldMapWith" K.toNull K.sourceFoldMapWith
59+ , benchIO "foldMapWithM" K.toNull K.sourceFoldMapWithM
60+ ]
61+ , bgroup "elimination"
62+ [ benchFold "toList" K.toList K.sourceUnfoldrM
63+ , benchFold "fold" K.foldl K.sourceUnfoldrM
64+ , benchFold "last" K.last K.sourceUnfoldrM
65+ ]
66+ , bgroup "transformation"
67+ [ benchIO "scan" K.scan K.sourceUnfoldrM
68+ , benchIO "map" K.map K.sourceUnfoldrM
69+ , benchIO "mapM" K.mapM K.sourceUnfoldrM
70+ , benchIO "concat" K.concat K.sourceUnfoldrM
71+ ]
72+ , bgroup "filtering"
73+ [ benchIO "filter-even" K.filterEven K.sourceUnfoldrM
74+ , benchIO "filter-all-out" K.filterAllOut K.sourceUnfoldrM
75+ , benchIO "filter-all-in" K.filterAllIn K.sourceUnfoldrM
76+ , benchIO "take-all" K.takeAll K.sourceUnfoldrM
77+ , benchIO "takeWhile-true" K.takeWhileTrue K.sourceUnfoldrM
78+ , benchIO "drop-all" K.dropAll K.sourceUnfoldrM
79+ , benchIO "dropWhile-true" K.dropWhileTrue K.sourceUnfoldrM
80+ ]
81+ , benchIO "zip" K.zip K.sourceUnfoldrM
82+ , bgroup "compose"
83+ [ benchIO "mapM" K.composeMapM K.sourceUnfoldrM
84+ , benchIO "map-with-all-in-filter" K.composeMapAllInFilter K.sourceUnfoldrM
85+ , benchIO "all-in-filters" K.composeAllInFilters K.sourceUnfoldrM
86+ , benchIO "all-out-filters" K.composeAllOutFilters K.sourceUnfoldrM
87+ ]
88+ -- Scaling with same operation in sequence
89+ , bgroup "compose-scaling"
90+ [ benchIO "1" (K.composeScaling 1) K.sourceUnfoldrM
91+ , benchIO "2" (K.composeScaling 2) K.sourceUnfoldrM
92+ , benchIO "3" (K.composeScaling 3) K.sourceUnfoldrM
93+ , benchIO "4" (K.composeScaling 4) K.sourceUnfoldrM
94+ ]
95+ ]
96+ ]
benchmark/Linear.hs+12−9
@@ -37,10 +37,13 @@ main = do
3737 defaultMain
3838 [ bgroup "serially"
3939 [ bgroup "generation"
40− [ benchSrcIO serially "unfoldr" $ Ops.sourceUnfoldr
40+ [ -- Most basic, barely stream continuations running
41+ benchSrcIO serially "unfoldr" $ Ops.sourceUnfoldr
4142 , benchSrcIO serially "unfoldrM" Ops.sourceUnfoldrM
43+ -- These are essentially cons and consM
4244 , benchSrcIO serially "fromFoldable" Ops.sourceFromFoldable
4345 , benchSrcIO serially "fromFoldableM" Ops.sourceFromFoldableM
46+ -- These are essentially appends
4447 , benchSrcIO serially "foldMapWith" Ops.sourceFoldMapWith
4548 , benchSrcIO serially "foldMapWithM" Ops.sourceFoldMapWithM
4649 ]
@@ -81,19 +84,19 @@ main = do
8184 ]
8285 , bgroup "asyncly"
8386 [ -- benchIO "unfoldr" $ Ops.toNull asyncly
84− -- , benchSrcIO asyncly "fromFoldable" Ops.sourceFromFoldable
8587 benchSrcIO asyncly "unfoldrM" Ops.sourceUnfoldrM
88+ -- , benchSrcIO asyncly "fromFoldable" Ops.sourceFromFoldable
8689 , benchSrcIO asyncly "fromFoldableM" Ops.sourceFromFoldableM
87− , benchSrcIO asyncly "foldMapWith" Ops.sourceFoldMapWith
90+ -- , benchSrcIO asyncly "foldMapWith" Ops.sourceFoldMapWith
8891 , benchSrcIO asyncly "foldMapWithM" Ops.sourceFoldMapWithM
8992 , benchIO "mapM" $ Ops.mapM asyncly
9093 ]
9194 , bgroup "wAsyncly"
9295 [ -- benchIO "unfoldr" $ Ops.toNull wAsyncly
93− -- , benchSrcIO wAsyncly "fromFoldable" Ops.sourceFromFoldable
9496 benchSrcIO wAsyncly "unfoldrM" Ops.sourceUnfoldrM
97+ -- , benchSrcIO wAsyncly "fromFoldable" Ops.sourceFromFoldable
9598 , benchSrcIO wAsyncly "fromFoldableM" Ops.sourceFromFoldableM
96− , benchSrcIO wAsyncly "foldMapWith" Ops.sourceFoldMapWith
99+ -- , benchSrcIO wAsyncly "foldMapWith" Ops.sourceFoldMapWith
97100 , benchSrcIO wAsyncly "foldMapWithM" Ops.sourceFoldMapWithM
98101 , benchIO "mapM" $ Ops.mapM wAsyncly
99102 ]
@@ -101,20 +104,20 @@ main = do
101104 -- all stream types.
102105 , bgroup "aheadly"
103106 [ -- benchIO "unfoldr" $ Ops.toNull aheadly
104− -- , benchSrcIO aheadly "fromFoldable" Ops.sourceFromFoldable
105107 benchSrcIO aheadly "unfoldrM" Ops.sourceUnfoldrM
108+ -- , benchSrcIO aheadly "fromFoldable" Ops.sourceFromFoldable
106109 , benchSrcIO aheadly "fromFoldableM" Ops.sourceFromFoldableM
107− , benchSrcIO aheadly "foldMapWith" Ops.sourceFoldMapWith
110+ -- , benchSrcIO aheadly "foldMapWith" Ops.sourceFoldMapWith
108111 , benchSrcIO aheadly "foldMapWithM" Ops.sourceFoldMapWithM
109112 , benchIO "mapM" $ Ops.mapM aheadly
110113 ]
111114 -- XXX need to use smaller streams to finish in reasonable time
112115 , bgroup "parallely"
113116 [ --benchIO "unfoldr" $ Ops.toNull parallely
114− --, benchSrcIO parallely "fromFoldable" Ops.sourceFromFoldable
115117 benchSrcIO parallely "unfoldrM" Ops.sourceUnfoldrM
118+ --, benchSrcIO parallely "fromFoldable" Ops.sourceFromFoldable
116119 , benchSrcIO parallely "fromFoldableM" Ops.sourceFromFoldableM
117− , benchSrcIO parallely "foldMapWith" Ops.sourceFoldMapWith
120+ -- , benchSrcIO parallely "foldMapWith" Ops.sourceFoldMapWith
118121 , benchSrcIO parallely "foldMapWithM" Ops.sourceFoldMapWithM
119122 , benchIO "mapM" $ Ops.mapM parallely
120123 -- Zip has only one parallel flavor
benchmark/StreamDOps.hsnew file+179
@@ -0,0 +1,179 @@
1+-- |
2+-- Module : StreamDOps
3+-- Copyright : (c) 2018 Harendra Kumar
4+--
5+-- License : BSD3
6+-- Maintainer : harendra.kumar@gmail.com
7+
8+{-# LANGUAGE FlexibleContexts #-}
9+
10+module StreamDOps where
11+
12+-- import Prelude
13+ -- (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
14+ -- subtract, undefined, Maybe(..))
15+import Prelude
16+ (Monad, Int, (+), (.), return, (>),
17+ Maybe(..))
18+
19+import qualified Streamly.Streams.StreamD as S
20+
21+value, maxValue :: Int
22+value = 1000000
23+maxValue = value + 1000
24+
25+-------------------------------------------------------------------------------
26+-- Benchmark ops
27+-------------------------------------------------------------------------------
28+
29+{-
30+{-# INLINE scan #-}
31+{-# INLINE map #-}
32+{-# INLINE filterEven #-}
33+{-# INLINE filterAllOut #-}
34+{-# INLINE filterAllIn #-}
35+{-# INLINE takeOne #-}
36+{-# INLINE takeAll #-}
37+{-# INLINE takeWhileTrue #-}
38+{-# INLINE dropAll #-}
39+{-# INLINE dropWhileTrue #-}
40+{-# INLINE zip #-}
41+{-# INLINE concat #-}
42+{-# INLINE composeAllInFilters #-}
43+{-# INLINE composeAllOutFilters #-}
44+{-# INLINE composeMapAllInFilter #-}
45+scan, map, filterEven, filterAllOut,
46+ filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue, zip,
47+ concat, composeAllInFilters, composeAllOutFilters,
48+ composeMapAllInFilter
49+ :: Monad m
50+ => Stream m Int -> m ()
51+
52+{-# INLINE composeMapM #-}
53+composeMapM :: S.MonadAsync m => Stream m Int -> m ()
54+
55+{-# INLINE toList #-}
56+toList :: Monad m => Stream m Int -> m [Int]
57+{-# INLINE foldl #-}
58+foldl :: Monad m => Stream m Int -> m Int
59+{-# INLINE last #-}
60+last :: Monad m => Stream m Int -> m (Maybe Int)
61+{-# INLINE zipAsync #-}
62+zipAsync :: S.MonadAsync m => Stream m Int -> m ()
63+-}
64+
65+{-# INLINE toNull #-}
66+{-# INLINE mapM #-}
67+toNull, mapM :: Monad m => Stream m Int -> m ()
68+
69+-------------------------------------------------------------------------------
70+-- Stream generation and elimination
71+-------------------------------------------------------------------------------
72+
73+type Stream m a = S.Stream m a
74+
75+{-# INLINE sourceUnfoldr #-}
76+sourceUnfoldr :: Monad m => Int -> Stream m Int
77+sourceUnfoldr n = S.unfoldr step n
78+ where
79+ step cnt =
80+ if cnt > n + value
81+ then Nothing
82+ else (Just (cnt, cnt + 1))
83+
84+{-# INLINE sourceUnfoldrM #-}
85+sourceUnfoldrM :: Monad m => Int -> Stream m Int
86+sourceUnfoldrM n = S.unfoldrM step n
87+ where
88+ step cnt =
89+ if cnt > n + value
90+ then return Nothing
91+ else return (Just (cnt, cnt + 1))
92+
93+{-# INLINE sourceFromEnum #-}
94+sourceFromEnum :: Monad m => Int -> Stream m Int
95+sourceFromEnum n = S.enumFromStepN n 1 value
96+
97+{-# INLINE sourceFromFoldable #-}
98+sourceFromFoldable :: Monad m => Int -> Stream m Int
99+sourceFromFoldable n = S.fromList [n..n+value]
100+
101+{-
102+{-# INLINE sourceFromFoldableM #-}
103+sourceFromFoldableM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
104+sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
105+-}
106+
107+{-# INLINE source #-}
108+source :: Monad m => Int -> Stream m Int
109+source n = sourceUnfoldrM n
110+
111+-------------------------------------------------------------------------------
112+-- Elimination
113+-------------------------------------------------------------------------------
114+
115+{-# INLINE runStream #-}
116+runStream :: Monad m => Stream m a -> m ()
117+runStream = S.runStream
118+
119+toNull = runStream
120+{-
121+toList = S.toList
122+foldl = S.foldl' (+) 0
123+last = S.last
124+-}
125+
126+-------------------------------------------------------------------------------
127+-- Transformation
128+-------------------------------------------------------------------------------
129+
130+{-# INLINE transform #-}
131+transform :: Monad m => Stream m a -> m ()
132+transform = runStream
133+
134+{-
135+scan = transform . S.scanl' (+) 0
136+map = transform . fmap (+1)
137+-}
138+mapM = transform . S.mapM return
139+{-
140+filterEven = transform . S.filter even
141+filterAllOut = transform . S.filter (> maxValue)
142+filterAllIn = transform . S.filter (<= maxValue)
143+takeOne = transform . S.take 1
144+takeAll = transform . S.take maxValue
145+takeWhileTrue = transform . S.takeWhile (<= maxValue)
146+dropAll = transform . S.drop maxValue
147+dropWhileTrue = transform . S.dropWhile (<= maxValue)
148+
149+-------------------------------------------------------------------------------
150+-- Zipping and concat
151+-------------------------------------------------------------------------------
152+
153+zip src = transform $ (S.zipWith (,) src src)
154+concat _n = return ()
155+
156+-------------------------------------------------------------------------------
157+-- Composition
158+-------------------------------------------------------------------------------
159+
160+{-# INLINE compose #-}
161+compose :: Monad m => (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
162+compose f = transform . f . f . f . f
163+
164+composeMapM = compose (S.mapM return)
165+composeAllInFilters = compose (S.filter (<= maxValue))
166+composeAllOutFilters = compose (S.filter (> maxValue))
167+composeMapAllInFilter = compose (S.filter (<= maxValue) . fmap (subtract 1))
168+
169+{-# INLINABLE composeScaling #-}
170+composeScaling :: Monad m => Int -> Stream m Int -> m ()
171+composeScaling m =
172+ case m of
173+ 1 -> transform . f
174+ 2 -> transform . f . f
175+ 3 -> transform . f . f . f
176+ 4 -> transform . f . f . f . f
177+ _ -> undefined
178+ where f = S.filter (<= maxValue)
179+ -}
benchmark/StreamKOps.hsnew file+178
@@ -0,0 +1,178 @@
1+-- |
2+-- Module : StreamKOps
3+-- Copyright : (c) 2018 Harendra Kumar
4+--
5+-- License : BSD3
6+-- Maintainer : harendra.kumar@gmail.com
7+
8+{-# LANGUAGE FlexibleContexts #-}
9+
10+module StreamKOps where
11+
12+import Prelude
13+ (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=),
14+ subtract, undefined, Maybe(..))
15+
16+import qualified Streamly.Streams.StreamK as S hiding (runStream)
17+-- import qualified Streamly.Streams.Serial as S
18+import qualified Streamly as S
19+import qualified Streamly.Prelude as S
20+
21+value, maxValue :: Int
22+value = 1000000
23+maxValue = value + 1000
24+
25+-------------------------------------------------------------------------------
26+-- Benchmark ops
27+-------------------------------------------------------------------------------
28+
29+{-# INLINE scan #-}
30+{-# INLINE map #-}
31+{-# INLINE filterEven #-}
32+{-# INLINE filterAllOut #-}
33+{-# INLINE filterAllIn #-}
34+{-# INLINE takeOne #-}
35+{-# INLINE takeAll #-}
36+{-# INLINE takeWhileTrue #-}
37+{-# INLINE dropAll #-}
38+{-# INLINE dropWhileTrue #-}
39+{-# INLINE zip #-}
40+{-# INLINE concat #-}
41+{-# INLINE composeAllInFilters #-}
42+{-# INLINE composeAllOutFilters #-}
43+{-# INLINE composeMapAllInFilter #-}
44+scan, map, filterEven, filterAllOut,
45+ filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropWhileTrue, zip,
46+ concat, composeAllInFilters, composeAllOutFilters,
47+ composeMapAllInFilter
48+ :: Monad m
49+ => Stream m Int -> m ()
50+
51+{-# INLINE composeMapM #-}
52+composeMapM :: S.MonadAsync m => Stream m Int -> m ()
53+
54+{-# INLINE toList #-}
55+toList :: Monad m => Stream m Int -> m [Int]
56+{-# INLINE foldl #-}
57+foldl :: Monad m => Stream m Int -> m Int
58+{-# INLINE last #-}
59+last :: Monad m => Stream m Int -> m (Maybe Int)
60+
61+{-# INLINE toNull #-}
62+{-# INLINE mapM #-}
63+toNull :: Monad m => Stream m Int -> m ()
64+mapM :: S.MonadAsync m => Stream m Int -> m ()
65+
66+-------------------------------------------------------------------------------
67+-- Stream generation and elimination
68+-------------------------------------------------------------------------------
69+
70+type Stream m a = S.SerialT m a
71+
72+{-# INLINE sourceUnfoldr #-}
73+sourceUnfoldr :: Int -> Stream m Int
74+sourceUnfoldr n = S.unfoldr step n
75+ where
76+ step cnt =
77+ if cnt > n + value
78+ then Nothing
79+ else (Just (cnt, cnt + 1))
80+
81+{-# INLINE sourceUnfoldrM #-}
82+sourceUnfoldrM :: S.MonadAsync m => Int -> Stream m Int
83+sourceUnfoldrM n = S.unfoldrM step n
84+ where
85+ step cnt =
86+ if cnt > n + value
87+ then return Nothing
88+ else return (Just (cnt, cnt + 1))
89+
90+{-
91+{-# INLINE sourceFromEnum #-}
92+sourceFromEnum :: Monad m => Int -> Stream m Int
93+sourceFromEnum n = S.enumFromStepN n 1 value
94+-}
95+
96+{-# INLINE sourceFromFoldable #-}
97+sourceFromFoldable :: Int -> Stream m Int
98+sourceFromFoldable n = S.fromFoldable [n..n+value]
99+
100+{-# INLINE sourceFromFoldableM #-}
101+sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
102+sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
103+
104+{-# INLINE sourceFoldMapWith #-}
105+sourceFoldMapWith :: Monad m => Int -> Stream m Int
106+sourceFoldMapWith n = S.foldMapWith (S.<>) return [n..n+value]
107+
108+{-# INLINE sourceFoldMapWithM #-}
109+sourceFoldMapWithM :: Monad m => Int -> Stream m Int
110+sourceFoldMapWithM n = S.foldMapWith (S.<>) (S.yieldM . return) [n..n+value]
111+
112+{-# INLINE source #-}
113+source :: S.MonadAsync m => Int -> Stream m Int
114+source n = sourceUnfoldrM n
115+
116+-------------------------------------------------------------------------------
117+-- Elimination
118+-------------------------------------------------------------------------------
119+
120+{-# INLINE runStream #-}
121+runStream :: Monad m => Stream m a -> m ()
122+runStream = S.runStream
123+
124+toNull = runStream
125+toList = S.toList
126+foldl = S.foldl' (+) 0
127+last = S.last
128+
129+-------------------------------------------------------------------------------
130+-- Transformation
131+-------------------------------------------------------------------------------
132+
133+{-# INLINE transform #-}
134+transform :: Monad m => Stream m a -> m ()
135+transform = runStream
136+
137+scan = transform . S.scanl' (+) 0
138+map = transform . fmap (+1)
139+mapM = transform . S.mapM return
140+filterEven = transform . S.filter even
141+filterAllOut = transform . S.filter (> maxValue)
142+filterAllIn = transform . S.filter (<= maxValue)
143+takeOne = transform . S.take 1
144+takeAll = transform . S.take maxValue
145+takeWhileTrue = transform . S.takeWhile (<= maxValue)
146+dropAll = transform . S.drop maxValue
147+dropWhileTrue = transform . S.dropWhile (<= maxValue)
148+
149+-------------------------------------------------------------------------------
150+-- Zipping and concat
151+-------------------------------------------------------------------------------
152+
153+zip src = transform $ (S.zipWith (,) src src)
154+concat _n = return ()
155+
156+-------------------------------------------------------------------------------
157+-- Composition
158+-------------------------------------------------------------------------------
159+
160+{-# INLINE compose #-}
161+compose :: Monad m => (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
162+compose f = transform . f . f . f . f
163+
164+composeMapM = compose (S.mapM return)
165+composeAllInFilters = compose (S.filter (<= maxValue))
166+composeAllOutFilters = compose (S.filter (> maxValue))
167+composeMapAllInFilter = compose (S.filter (<= maxValue) . fmap (subtract 1))
168+
169+{-# INLINABLE composeScaling #-}
170+composeScaling :: Monad m => Int -> Stream m Int -> m ()
171+composeScaling m =
172+ case m of
173+ 1 -> transform . f
174+ 2 -> transform . f . f
175+ 3 -> transform . f . f . f
176+ 4 -> transform . f . f . f . f
177+ _ -> undefined
178+ where f = S.filter (<= maxValue)
streamly.cabal+47−1
@@ -108,7 +108,21 @@ flag examples-sdl
108108
109109library
110110 hs-source-dirs: src
111− other-modules: Streamly.SVar
111+ if flag(dev)
112+ exposed-modules:
113+ Streamly.SVar
114+ , Streamly.Streams.StreamK
115+ , Streamly.Streams.StreamD
116+ , Streamly.Streams.Serial
117+ , Streamly.Streams.SVar
118+ , Streamly.Streams.Async
119+ , Streamly.Streams.Parallel
120+ , Streamly.Streams.Ahead
121+ , Streamly.Streams.Zip
122+ , Streamly.Streams.Prelude
123+ else
124+ other-modules:
125+ Streamly.SVar
112126 , Streamly.Streams.StreamK
113127 , Streamly.Streams.StreamD
114128 , Streamly.Streams.Serial
@@ -253,6 +267,38 @@ test-suite parallel-loops
253267-- Benchmarks
254268-------------------------------------------------------------------------------
255269
270+benchmark base
271+ type: exitcode-stdio-1.0
272+ hs-source-dirs: benchmark
273+ main-is: BaseStreams.hs
274+ other-modules: StreamDOps
275+ , StreamKOps
276+ default-language: Haskell2010
277+ ghc-options: -O2 -Wall
278+ if flag(dev)
279+ ghc-options: -Wmissed-specialisations
280+ -Wall-missed-specialisations
281+ -fno-ignore-asserts
282+ if impl(ghc >= 8.0)
283+ ghc-options: -Wcompat
284+ -Wunrecognised-warning-flags
285+ -Widentities
286+ -Wincomplete-record-updates
287+ -Wincomplete-uni-patterns
288+ -Wredundant-constraints
289+ -Wnoncanonical-monad-instances
290+ -Wnoncanonical-monadfail-instances
291+ if flag(dev)
292+ buildable: True
293+ build-depends:
294+ streamly
295+ , base >= 4.8 && < 5
296+ , deepseq >= 1.4.0 && < 1.5
297+ , random >= 1.0 && < 2.0
298+ , gauge >= 0.2.1 && < 0.3
299+ else
300+ buildable: False
301+
256302benchmark linear
257303 type: exitcode-stdio-1.0
258304 hs-source-dirs: benchmark