on master help sign in
refactor "base" stream benchmarks

push the benchmark definitions from the top level "BaseStreams.hs" file to the individual stream modules to improve modularity.

commit166bd9326748e67d9fb1460e5fc4e9fb7cf9dea5 authorHarendra Kumar <harendra.kumar@gmail.com> dateThu 20 Feb 2020, 18:29 (7 years ago) parentae30f2f
8 files changed+551−426
benchmark/BaseStreams.hs−368 benchmark/Streamly/Benchmark/Data/Stream/BaseStreams.hs+40 benchmark/Streamly/Benchmark/Data/Stream/StreamD.hs+202−18 benchmark/Streamly/Benchmark/Data/Stream/StreamDK.hs+38−9 benchmark/Streamly/Benchmark/Data/Stream/StreamK.hs+221−22 benchmark/lib/Streamly/Benchmark/Common.hs+8 benchmark/streamly-benchmarks.cabal+41−9 streamly.cabal+1
benchmark/BaseStreams.hsdeleted−368
@@ -1,368 +0,0 @@
1−-- |
2−-- Module : Main
3−-- Copyright : (c) 2018 Harendra Kumar
4−--
5−-- License : BSD3
6−-- Maintainer : streamly@composewell.com
7−
8−{-# LANGUAGE CPP #-}
9−
10−import Control.DeepSeq (NFData(..))
11−-- import Data.Functor.Identity (Identity, runIdentity)
12−import System.Random (randomRIO)
13−
14−import Gauge
15−import qualified Streamly.Benchmark.Data.Stream.StreamD as D
16−import qualified Streamly.Benchmark.Data.Stream.StreamK as K
17−import qualified Streamly.Benchmark.Data.Stream.StreamDK as DK
18−import qualified Data.List as List
19−
20−#if !MIN_VERSION_deepseq(1,4,3)
21−instance NFData Ordering where rnf = (`seq` ())
22−#endif
23−
24−-- We need a monadic bind here to make sure that the function f does not get
25−-- completely optimized out by the compiler in some cases.
26−{-# INLINE benchFold #-}
27−benchFold :: NFData b
28− => String -> (t IO Int -> IO b) -> (Int -> t IO Int) -> Benchmark
29−benchFold name f src = bench name $ nfIO $ randomRIO (1,1) >>= f . src
30−
31−{-# INLINE benchPure #-}
32−benchPure :: String -> ([Int] -> [Int]) -> (Int -> [Int]) -> Benchmark
33−benchPure name run f = bench name $ nfIO $ randomRIO (1,1) >>= return . run . f
34−
35−#if defined(O_N_STACK)
36−-- | Takes a source, and uses it with a default drain/fold method.
37−{-# INLINE benchD #-}
38−benchD :: String -> (Int -> D.Stream IO Int) -> Benchmark
39−benchD name f = bench name $ nfIO $ randomRIO (1,1) >>= D.toNull . f
40−
41−{-# INLINE benchK #-}
42−benchK :: String -> (Int -> K.Stream IO Int) -> Benchmark
43−benchK name f = bench name $ nfIO $ randomRIO (1,1) >>= K.toNull . f
44−#endif
45−
46−main :: IO ()
47−main =
48− defaultMain
49−#ifdef O_1_SPACE
50− [ bgroup "streamD"
51− [ bgroup "generation"
52− [ benchFold "unfoldr" D.toNull D.sourceUnfoldr
53− , benchFold "unfoldrM" D.toNull D.sourceUnfoldrM
54− , benchFold "intFromTo" D.toNull D.sourceIntFromTo
55−
56− , benchFold "fromList" D.toNull D.sourceFromList
57− -- , benchFold "fromFoldableM" D.sourceFromFoldableM
58− ]
59− , bgroup "elimination"
60− [ benchFold "toNull" D.toNull D.sourceUnfoldrM
61− , benchFold "mapM_" D.mapM_ D.sourceUnfoldrM
62− , benchFold "uncons" D.uncons D.sourceUnfoldrM
63− , benchFold "foldl'" D.foldl D.sourceUnfoldrM
64− , benchFold "last" D.last D.sourceUnfoldrM
65− ]
66− , bgroup "nested"
67− [ benchFold "toNullAp" D.toNullApNested (D.sourceUnfoldrMN D.value2)
68− , benchFold "toNull" D.toNullNested (D.sourceUnfoldrMN D.value2)
69− , benchFold "toNull3" D.toNullNested3 (D.sourceUnfoldrMN D.value3)
70− , benchFold "filterAllIn" D.filterAllInNested (D.sourceUnfoldrMN K.value2)
71− , benchFold "filterAllOut" D.filterAllOutNested (D.sourceUnfoldrMN K.value2)
72− , benchFold "toNullApPure" D.toNullApNested (D.sourceUnfoldrN K.value2)
73− , benchFold "toNullPure" D.toNullNested (D.sourceUnfoldrN K.value2)
74− , benchFold "toNull3Pure" D.toNullNested3 (D.sourceUnfoldrN K.value3)
75− , benchFold "filterAllInPure" D.filterAllInNested (D.sourceUnfoldrN K.value2)
76− , benchFold "filterAllOutPure" D.filterAllOutNested (D.sourceUnfoldrN K.value2)
77− ]
78− , bgroup "transformation"
79− [ benchFold "scan" (D.scan 1) D.sourceUnfoldrM
80− , benchFold "map" (D.map 1) D.sourceUnfoldrM
81− , benchFold "fmap" (D.fmap 1) D.sourceUnfoldrM
82− , benchFold "mapM" (D.mapM 1) D.sourceUnfoldrM
83− , benchFold "mapMaybe" (D.mapMaybe 1) D.sourceUnfoldrM
84− , benchFold "mapMaybeM" (D.mapMaybeM 1) D.sourceUnfoldrM
85− , benchFold "concatMapNxN" (D.concatMap 1) (D.sourceUnfoldrMN D.value2)
86− , benchFold "concatMapRepl4xN" D.concatMapRepl4xN
87− (D.sourceUnfoldrMN (D.value `div` 4))
88− , benchFold "concatMapPureNxN" (D.concatMap 1) (D.sourceUnfoldrN D.value2)
89− , benchFold "concatMapURepl4xN" D.concatMapURepl4xN
90− (D.sourceUnfoldrMN (D.value `div` 4))
91− -- , benchFold "intersperse" (D.intersperse 1) (D.sourceUnfoldrMN D.value2)
92− -- , benchFold "interspersePure" (D.intersperse 1) (D.sourceUnfoldrN D.value2)
93− -- , benchFold "foldrS" (D.foldrS 1) D.sourceUnfoldrM
94− -- This has horrible performance, never finishes
95− -- , benchFold "foldlS" (D.foldlS 1) D.sourceUnfoldrM
96− ]
97− , bgroup "transformationX4"
98− [ benchFold "scan" (D.scan 4) D.sourceUnfoldrM
99− , benchFold "map" (D.map 4) D.sourceUnfoldrM
100− , benchFold "fmap" (D.fmap 4) D.sourceUnfoldrM
101− , benchFold "mapM" (D.mapM 4) D.sourceUnfoldrM
102− , benchFold "mapMaybe" (D.mapMaybe 4) D.sourceUnfoldrM
103− , benchFold "mapMaybeM" (D.mapMaybeM 4) D.sourceUnfoldrM
104− -- , benchFold "concatMap" (D.concatMap 4) (D.sourceUnfoldrMN D.value16)
105− -- , benchFold "intersperse" (D.intersperse 4) (D.sourceUnfoldrMN D.value16)
106− ]
107− , bgroup "filtering"
108− [ benchFold "filter-even" (D.filterEven 1) D.sourceUnfoldrM
109− , benchFold "filter-all-out" (D.filterAllOut 1) D.sourceUnfoldrM
110− , benchFold "filter-all-in" (D.filterAllIn 1) D.sourceUnfoldrM
111− , benchFold "take-all" (D.takeAll 1) D.sourceUnfoldrM
112− , benchFold "takeWhile-true" (D.takeWhileTrue 1) D.sourceUnfoldrM
113− , benchFold "drop-one" (D.dropOne 1) D.sourceUnfoldrM
114− , benchFold "drop-all" (D.dropAll 1) D.sourceUnfoldrM
115− , benchFold "dropWhile-true" (D.dropWhileTrue 1) D.sourceUnfoldrM
116− , benchFold "dropWhile-false" (D.dropWhileFalse 1) D.sourceUnfoldrM
117− ]
118− , bgroup "filteringX4"
119− [ benchFold "filter-even" (D.filterEven 4) D.sourceUnfoldrM
120− , benchFold "filter-all-out" (D.filterAllOut 4) D.sourceUnfoldrM
121− , benchFold "filter-all-in" (D.filterAllIn 4) D.sourceUnfoldrM
122− , benchFold "take-all" (D.takeAll 4) D.sourceUnfoldrM
123− , benchFold "takeWhile-true" (D.takeWhileTrue 4) D.sourceUnfoldrM
124− , benchFold "drop-one" (D.dropOne 4) D.sourceUnfoldrM
125− , benchFold "drop-all" (D.dropAll 4) D.sourceUnfoldrM
126− , benchFold "dropWhile-true" (D.dropWhileTrue 4) D.sourceUnfoldrM
127− , benchFold "dropWhile-false" (D.dropWhileFalse 4) D.sourceUnfoldrM
128− ]
129− , bgroup "zipping"
130− [ benchFold "eqBy" D.eqBy D.sourceUnfoldrM
131− , benchFold "cmpBy" D.cmpBy D.sourceUnfoldrM
132− , benchFold "zip" D.zip D.sourceUnfoldrM
133− ]
134− , bgroup "mixed"
135− [ benchFold "scan-map" (D.scanMap 1) D.sourceUnfoldrM
136− , benchFold "drop-map" (D.dropMap 1) D.sourceUnfoldrM
137− , benchFold "drop-scan" (D.dropScan 1) D.sourceUnfoldrM
138− , benchFold "take-drop" (D.takeDrop 1) D.sourceUnfoldrM
139− , benchFold "take-scan" (D.takeScan 1) D.sourceUnfoldrM
140− , benchFold "take-map" (D.takeMap 1) D.sourceUnfoldrM
141− , benchFold "filter-drop" (D.filterDrop 1) D.sourceUnfoldrM
142− , benchFold "filter-take" (D.filterTake 1) D.sourceUnfoldrM
143− , benchFold "filter-scan" (D.filterScan 1) D.sourceUnfoldrM
144− , benchFold "filter-map" (D.filterMap 1) D.sourceUnfoldrM
145− ]
146− , bgroup "mixedX2"
147− [ benchFold "scan-map" (D.scanMap 2) D.sourceUnfoldrM
148− , benchFold "drop-map" (D.dropMap 2) D.sourceUnfoldrM
149− , benchFold "drop-scan" (D.dropScan 2) D.sourceUnfoldrM
150− , benchFold "take-drop" (D.takeDrop 2) D.sourceUnfoldrM
151− , benchFold "take-scan" (D.takeScan 2) D.sourceUnfoldrM
152− , benchFold "take-map" (D.takeMap 2) D.sourceUnfoldrM
153− , benchFold "filter-drop" (D.filterDrop 2) D.sourceUnfoldrM
154− , benchFold "filter-take" (D.filterTake 2) D.sourceUnfoldrM
155− , benchFold "filter-scan" (D.filterScan 2) D.sourceUnfoldrM
156− , benchFold "filter-map" (D.filterMap 2) D.sourceUnfoldrM
157− ]
158− , bgroup "mixedX4"
159− [ benchFold "scan-map" (D.scanMap 4) D.sourceUnfoldrM
160− , benchFold "drop-map" (D.dropMap 4) D.sourceUnfoldrM
161− , benchFold "drop-scan" (D.dropScan 4) D.sourceUnfoldrM
162− , benchFold "take-drop" (D.takeDrop 4) D.sourceUnfoldrM
163− , benchFold "take-scan" (D.takeScan 4) D.sourceUnfoldrM
164− , benchFold "take-map" (D.takeMap 4) D.sourceUnfoldrM
165− , benchFold "filter-drop" (D.filterDrop 4) D.sourceUnfoldrM
166− , benchFold "filter-take" (D.filterTake 4) D.sourceUnfoldrM
167− , benchFold "filter-scan" (D.filterScan 4) D.sourceUnfoldrM
168− , benchFold "filter-map" (D.filterMap 4) D.sourceUnfoldrM
169− ]
170− ]
171− , bgroup "list"
172− [ bgroup "elimination"
173− [ benchPure "last" (\xs -> [List.last xs]) (K.sourceUnfoldrList K.value)
174− ]
175− , bgroup "nested"
176− [ benchPure "toNullAp" K.toNullApNestedList (K.sourceUnfoldrList K.value2)
177− , benchPure "toNull" K.toNullNestedList (K.sourceUnfoldrList K.value2)
178− , benchPure "toNull3" K.toNullNestedList3 (K.sourceUnfoldrList K.value3)
179− , benchPure "filterAllIn" K.filterAllInNestedList (K.sourceUnfoldrList K.value2)
180− , benchPure "filterAllOut" K.filterAllOutNestedList (K.sourceUnfoldrList K.value2)
181− ]
182− ]
183− , bgroup "streamK"
184− [ bgroup "generation"
185− [ benchFold "unfoldr" K.toNull K.sourceUnfoldr
186− , benchFold "unfoldrM" K.toNull K.sourceUnfoldrM
187− -- , benchFold "fromEnum" K.toNull K.sourceFromEnum
188−
189− , benchFold "fromFoldable" K.toNull K.sourceFromFoldable
190− -- , benchFold "fromFoldableM" K.toNull K.sourceFromFoldableM
191−
192− -- appends
193− , benchFold "foldMapWith" K.toNull K.sourceFoldMapWith
194− , benchFold "foldMapWithM" K.toNull K.sourceFoldMapWithM
195− ]
196− , bgroup "elimination"
197− [ benchFold "toNull" K.toNull K.sourceUnfoldrM
198− , benchFold "mapM_" K.mapM_ K.sourceUnfoldrM
199− , benchFold "uncons" K.uncons K.sourceUnfoldrM
200− , benchFold "init" K.init K.sourceUnfoldrM
201− , benchFold "foldl'" K.foldl K.sourceUnfoldrM
202− , benchFold "last" K.last K.sourceUnfoldrM
203− ]
204− , bgroup "nested"
205− [ benchFold "toNullAp" K.toNullApNested (K.sourceUnfoldrMN K.value2)
206− , benchFold "toNull" K.toNullNested (K.sourceUnfoldrMN K.value2)
207− , benchFold "toNull3" K.toNullNested3 (K.sourceUnfoldrMN K.value3)
208− , benchFold "filterAllIn" K.filterAllInNested (K.sourceUnfoldrMN K.value2)
209− , benchFold "filterAllOut" K.filterAllOutNested (K.sourceUnfoldrMN K.value2)
210− , benchFold "toNullApPure" K.toNullApNested (K.sourceUnfoldrN K.value2)
211− , benchFold "toNullPure" K.toNullNested (K.sourceUnfoldrN K.value2)
212− , benchFold "toNull3Pure" K.toNullNested3 (K.sourceUnfoldrN K.value3)
213− , benchFold "filterAllInPure" K.filterAllInNested (K.sourceUnfoldrN K.value2)
214− , benchFold "filterAllOutPure" K.filterAllOutNested (K.sourceUnfoldrN K.value2)
215− ]
216− , bgroup "transformation"
217− [ benchFold "scan" (K.scan 1) K.sourceUnfoldrM
218− , benchFold "map" (K.map 1) K.sourceUnfoldrM
219− , benchFold "fmap" (K.fmap 1) K.sourceUnfoldrM
220− , benchFold "mapM" (K.mapM 1) K.sourceUnfoldrM
221− , benchFold "mapMSerial" (K.mapMSerial 1) K.sourceUnfoldrM
222− -- , benchFoldSrcK "concatMap" K.concatMap
223− , benchFold "concatMapNxN" (K.concatMap 1) (K.sourceUnfoldrMN K.value2)
224− , benchFold "concatMapPureNxN" (K.concatMap 1) (K.sourceUnfoldrN K.value2)
225− , benchFold "concatMapRepl4xN" K.concatMapRepl4xN
226− (K.sourceUnfoldrMN (K.value `div` 4))
227− -- , benchFold "intersperse" (K.intersperse 1) (K.sourceUnfoldrMN K.value2)
228− -- , benchFold "interspersePure" (K.intersperse 1) (K.sourceUnfoldrN K.value2)
229− ]
230− , bgroup "transformationX4"
231− [ benchFold "scan" (K.scan 4) K.sourceUnfoldrM
232− , benchFold "map" (K.map 4) K.sourceUnfoldrM
233− , benchFold "fmap" (K.fmap 4) K.sourceUnfoldrM
234− , benchFold "mapM" (K.mapM 4) K.sourceUnfoldrM
235− , benchFold "mapMSerial" (K.mapMSerial 4) K.sourceUnfoldrM
236− -- , benchFold "concatMap" (K.concatMap 4) (K.sourceUnfoldrMN K.value16)
237− -- , benchFold "intersperse" (K.intersperse 4) (K.sourceUnfoldrMN K.value16)
238− ]
239− , bgroup "filtering"
240− [ benchFold "filter-even" (K.filterEven 1) K.sourceUnfoldrM
241− , benchFold "filter-all-out" (K.filterAllOut 1) K.sourceUnfoldrM
242− , benchFold "filter-all-in" (K.filterAllIn 1) K.sourceUnfoldrM
243− , benchFold "take-all" (K.takeAll 1) K.sourceUnfoldrM
244− , benchFold "takeWhile-true" (K.takeWhileTrue 1) K.sourceUnfoldrM
245− , benchFold "drop-one" (K.dropOne 1) K.sourceUnfoldrM
246− , benchFold "drop-all" (K.dropAll 1) K.sourceUnfoldrM
247− , benchFold "dropWhile-true" (K.dropWhileTrue 1) K.sourceUnfoldrM
248− , benchFold "dropWhile-false" (K.dropWhileFalse 1) K.sourceUnfoldrM
249− ]
250− , bgroup "filteringX4"
251− [ benchFold "filter-even" (K.filterEven 4) K.sourceUnfoldrM
252− , benchFold "filter-all-out" (K.filterAllOut 4) K.sourceUnfoldrM
253− , benchFold "filter-all-in" (K.filterAllIn 4) K.sourceUnfoldrM
254− , benchFold "take-all" (K.takeAll 4) K.sourceUnfoldrM
255− , benchFold "takeWhile-true" (K.takeWhileTrue 4) K.sourceUnfoldrM
256− , benchFold "drop-one" (K.dropOne 4) K.sourceUnfoldrM
257− , benchFold "drop-all" (K.dropAll 4) K.sourceUnfoldrM
258− , benchFold "dropWhile-true" (K.dropWhileTrue 4) K.sourceUnfoldrM
259− , benchFold "dropWhile-false" (K.dropWhileFalse 4) K.sourceUnfoldrM
260− ]
261− , bgroup "zipping"
262− [ benchFold "zip" K.zip K.sourceUnfoldrM
263− ]
264− , bgroup "mixed"
265− [ benchFold "scan-map" (K.scanMap 1) K.sourceUnfoldrM
266− , benchFold "drop-map" (K.dropMap 1) K.sourceUnfoldrM
267− , benchFold "drop-scan" (K.dropScan 1) K.sourceUnfoldrM
268− , benchFold "take-drop" (K.takeDrop 1) K.sourceUnfoldrM
269− , benchFold "take-scan" (K.takeScan 1) K.sourceUnfoldrM
270− , benchFold "take-map" (K.takeMap 1) K.sourceUnfoldrM
271− , benchFold "filter-drop" (K.filterDrop 1) K.sourceUnfoldrM
272− , benchFold "filter-take" (K.filterTake 1) K.sourceUnfoldrM
273− , benchFold "filter-scan" (K.filterScan 1) K.sourceUnfoldrM
274− , benchFold "filter-map" (K.filterMap 1) K.sourceUnfoldrM
275− ]
276− , bgroup "mixedX2"
277− [ benchFold "scan-map" (K.scanMap 2) K.sourceUnfoldrM
278− , benchFold "drop-map" (K.dropMap 2) K.sourceUnfoldrM
279− , benchFold "drop-scan" (K.dropScan 2) K.sourceUnfoldrM
280− , benchFold "take-drop" (K.takeDrop 2) K.sourceUnfoldrM
281− , benchFold "take-scan" (K.takeScan 2) K.sourceUnfoldrM
282− , benchFold "take-map" (K.takeMap 2) K.sourceUnfoldrM
283− , benchFold "filter-drop" (K.filterDrop 2) K.sourceUnfoldrM
284− , benchFold "filter-take" (K.filterTake 2) K.sourceUnfoldrM
285− , benchFold "filter-scan" (K.filterScan 2) K.sourceUnfoldrM
286− , benchFold "filter-map" (K.filterMap 2) K.sourceUnfoldrM
287− ]
288− , bgroup "mixedX4"
289− [ benchFold "scan-map" (K.scanMap 4) K.sourceUnfoldrM
290− , benchFold "drop-map" (K.dropMap 4) K.sourceUnfoldrM
291− , benchFold "drop-scan" (K.dropScan 4) K.sourceUnfoldrM
292− , benchFold "take-drop" (K.takeDrop 4) K.sourceUnfoldrM
293− , benchFold "take-scan" (K.takeScan 4) K.sourceUnfoldrM
294− , benchFold "take-map" (K.takeMap 4) K.sourceUnfoldrM
295− , benchFold "filter-drop" (K.filterDrop 4) K.sourceUnfoldrM
296− , benchFold "filter-take" (K.filterTake 4) K.sourceUnfoldrM
297− , benchFold "filter-scan" (K.filterScan 4) K.sourceUnfoldrM
298− , benchFold "filter-map" (K.filterMap 4) K.sourceUnfoldrM
299− ]
300− ]
301− , bgroup "streamDK"
302− [ bgroup "generation"
303− [ benchFold "unfoldr" DK.toNull DK.sourceUnfoldr
304− , benchFold "unfoldrM" DK.toNull DK.sourceUnfoldrM
305− ]
306− , bgroup "elimination"
307− [ benchFold "toNull" DK.toNull DK.sourceUnfoldrM
308− , benchFold "uncons" DK.uncons DK.sourceUnfoldrM
309− ]
310− ]
311− ]
312−#elif defined(O_N_HEAP)
313− [ bgroup "streamK"
314− [ bgroup "transformation"
315− [ benchFold "foldlS" (K.foldlS 1) K.sourceUnfoldrM
316− ]
317− ]
318− ]
319−#elif defined(O_N_STACK)
320− [ bgroup "streamD"
321− [ bgroup "elimination"
322− [ benchFold "tail" D.tail D.sourceUnfoldrM
323− , benchFold "nullTail" D.nullTail D.sourceUnfoldrM
324− , benchFold "headTail" D.headTail D.sourceUnfoldrM
325− ]
326− , bgroup "iterated"
327− [ benchD "mapM" D.iterateMapM
328− , benchD "scan(1/10)" D.iterateScan
329− , benchD "filterEven" D.iterateFilterEven
330− , benchD "takeAll" D.iterateTakeAll
331− , benchD "dropOne" D.iterateDropOne
332− , benchD "dropWhileFalse(1/10)" D.iterateDropWhileFalse
333− , benchD "dropWhileTrue" D.iterateDropWhileTrue
334− , benchD "iterateM" D.iterateM
335− ]
336− ]
337− , bgroup "streamK"
338− [ bgroup "elimination"
339− [ benchFold "tail" K.tail K.sourceUnfoldrM
340− , benchFold "nullTail" K.nullTail K.sourceUnfoldrM
341− , benchFold "headTail" K.headTail K.sourceUnfoldrM
342− ]
343− , bgroup "iterated"
344− [ benchK "mapM" K.iterateMapM
345− , benchK "scan(1/10)" K.iterateScan
346− , benchK "filterEven" K.iterateFilterEven
347− , benchK "takeAll" K.iterateTakeAll
348− , benchK "dropOne" K.iterateDropOne
349− , benchK "dropWhileFalse(1/10)" K.iterateDropWhileFalse
350− , benchK "dropWhileTrue" K.iterateDropWhileTrue
351− ]
352− ]
353− ]
354−#elif defined(O_N_SPACE)
355− [ bgroup "streamD"
356− [ bgroup "elimination"
357− [ benchFold "toList" D.toList D.sourceUnfoldrM
358− ]
359− ]
360− , bgroup "streamK"
361− [ bgroup "elimination"
362− [ benchFold "toList" K.toList K.sourceUnfoldrM
363− ]
364− ]
365− ]
366−#else
367−#error "One of O_1_SPACE/O_N_HEAP/O_N_STACK/O_N_SPACE must be defined"
368−#endif
benchmark/Streamly/Benchmark/Data/Stream/BaseStreams.hsnew file+40
@@ -0,0 +1,40 @@
1+-- |
2+-- Module : Main
3+-- Copyright : (c) 2018 Harendra Kumar
4+--
5+-- License : BSD3
6+-- Maintainer : streamly@composewell.com
7+
8+{-# LANGUAGE CPP #-}
9+
10+import qualified Streamly.Benchmark.Data.Stream.StreamK as K
11+
12+#if !defined(O_N_HEAP)
13+import qualified Streamly.Benchmark.Data.Stream.StreamD as D
14+#endif
15+
16+#ifdef O_1_SPACE
17+import qualified Streamly.Benchmark.Data.Stream.StreamDK as DK
18+#endif
19+
20+import Gauge
21+
22+main :: IO ()
23+main =
24+ defaultMain $
25+#ifdef O_1_SPACE
26+ D.o_1_space
27+ ++ K.o_1_space_list
28+ ++ K.o_1_space
29+ ++ DK.o_1_space
30+#elif defined(O_N_HEAP)
31+ K.o_n_heap
32+#elif defined(O_N_STACK)
33+ D.o_n_stack
34+ ++ K.o_n_stack
35+#elif defined(O_N_SPACE)
36+ D.o_n_space
37+ ++ K.o_n_space
38+#else
39+#error "One of O_1_SPACE/O_N_HEAP/O_N_STACK/O_N_SPACE must be defined"
40+#endif
benchmark/Streamly/Benchmark/Data/Stream/StreamD.hs+202−18
@@ -8,7 +8,13 @@
88{-# LANGUAGE FlexibleContexts #-}
99{-# LANGUAGE ScopedTypeVariables #-}
1010
11−module Streamly.Benchmark.Data.Stream.StreamD where
11+module Streamly.Benchmark.Data.Stream.StreamD
12+ (
13+ o_1_space
14+ , o_n_stack
15+ , o_n_space
16+ )
17+where
1218
1319import Control.Monad (when)
1420import Data.Maybe (isJust)
@@ -16,11 +22,17 @@ import Prelude
1622 (Monad, Int, (+), ($), (.), return, (>), even, (<=), div,
1723 subtract, undefined, Maybe(..), not, (>>=),
1824 maxBound, fmap, odd, (==), flip, (<$>), (<*>), round, (/), (**), (<))
25+import System.Random (randomRIO)
26+
1927import qualified Prelude as P
2028
2129import qualified Streamly.Internal.Data.Stream.StreamD as S
2230import qualified Streamly.Internal.Data.Unfold as UF
2331
32+import Streamly.Benchmark.Common (benchFold)
33+import Gauge (bench, nfIO, bgroup, Benchmark)
34+
35+
2436-- We try to keep the total number of iterations same irrespective of nesting
2537-- of the loops so that the overhead is easy to compare.
2638value, value2, value3, value16, maxValue :: Int
@@ -80,10 +92,6 @@ sourceIntFromTo n = S.enumerateFromToIntegral n (n + value)
8092sourceFromList :: Monad m => Int -> Stream m Int
8193sourceFromList n = S.fromList [n..n+value]
8294
83−{-# INLINE source #-}
84−source :: Monad m => Int -> Stream m Int
85−source = sourceUnfoldrM
86−
8795-------------------------------------------------------------------------------
8896-- Elimination
8997-------------------------------------------------------------------------------
@@ -159,35 +167,35 @@ composeN n f =
159167
160168{-# INLINE scan #-}
161169{-# INLINE map #-}
162−{-# INLINE fmap #-}
170+{-# INLINE fmapD #-}
163171{-# INLINE mapM #-}
164172{-# INLINE mapMaybe #-}
165173{-# INLINE mapMaybeM #-}
166174{-# INLINE filterEven #-}
167175{-# INLINE filterAllOut #-}
168176{-# INLINE filterAllIn #-}
169−{-# INLINE takeOne #-}
177+{-# INLINE _takeOne #-}
170178{-# INLINE takeAll #-}
171179{-# INLINE takeWhileTrue #-}
172−{-# INLINE takeWhileMTrue #-}
180+{-# INLINE _takeWhileMTrue #-}
173181{-# INLINE dropOne #-}
174182{-# INLINE dropAll #-}
175183{-# INLINE dropWhileTrue #-}
176−{-# INLINE dropWhileMTrue #-}
184+{-# INLINE _dropWhileMTrue #-}
177185{-# INLINE dropWhileFalse #-}
178−{-# INLINE foldrS #-}
186+{-# INLINE _foldrS #-}
179187{-# INLINE foldlS #-}
180188{-# INLINE concatMap #-}
181189{-# INLINE intersperse #-}
182−scan, map, fmap, mapM, mapMaybe, mapMaybeM, filterEven, filterAllOut,
183− filterAllIn, takeOne, takeAll, takeWhileTrue, takeWhileMTrue, dropOne,
184− dropAll, dropWhileTrue, dropWhileMTrue, dropWhileFalse, foldrS, foldlS,
190+scan, map, fmapD, mapM, mapMaybe, mapMaybeM, filterEven, filterAllOut,
191+ filterAllIn, _takeOne, takeAll, takeWhileTrue, _takeWhileMTrue, dropOne,
192+ dropAll, dropWhileTrue, _dropWhileMTrue, dropWhileFalse, _foldrS, foldlS,
185193 concatMap, intersperse
186194 :: Monad m
187195 => Int -> Stream m Int -> m ()
188196
189197scan n = composeN n $ S.scanl' (+) 0
190−fmap n = composeN n $ Prelude.fmap (+1)
198+fmapD n = composeN n $ Prelude.fmap (+1)
191199map n = composeN n $ S.map (+1)
192200mapM n = composeN n $ S.mapM return
193201mapMaybe n = composeN n $ S.mapMaybe
@@ -197,16 +205,16 @@ mapMaybeM n = composeN n $ S.mapMaybeM
197205filterEven n = composeN n $ S.filter even
198206filterAllOut n = composeN n $ S.filter (> maxValue)
199207filterAllIn n = composeN n $ S.filter (<= maxValue)
200−takeOne n = composeN n $ S.take 1
208+_takeOne n = composeN n $ S.take 1
201209takeAll n = composeN n $ S.take maxValue
202210takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
203−takeWhileMTrue n = composeN n $ S.takeWhileM (return . (<= maxValue))
211+_takeWhileMTrue n = composeN n $ S.takeWhileM (return . (<= maxValue))
204212dropOne n = composeN n $ S.drop 1
205213dropAll n = composeN n $ S.drop maxValue
206214dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
207−dropWhileMTrue n = composeN n $ S.dropWhileM (return . (<= maxValue))
215+_dropWhileMTrue n = composeN n $ S.dropWhileM (return . (<= maxValue))
208216dropWhileFalse n = composeN n $ S.dropWhile (> maxValue)
209−foldrS n = composeN n $ S.foldrS S.cons S.nil
217+_foldrS n = composeN n $ S.foldrS S.cons S.nil
210218foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
211219concatMap n = composeN n $ (\s -> S.concatMap (\_ -> s) s)
212220intersperse n = composeN n $ S.intersperse maxValue
@@ -355,3 +363,179 @@ filterAllInNested str = runStream $ do
355363 if s > 0
356364 then return s
357365 else S.nil
366+
367+-------------------------------------------------------------------------------
368+-- Benchmarks
369+-------------------------------------------------------------------------------
370+
371+o_1_space :: [Benchmark]
372+o_1_space =
373+ [ bgroup "streamD"
374+ [ bgroup "generation"
375+ [ benchFold "unfoldr" toNull sourceUnfoldr
376+ , benchFold "unfoldrM" toNull sourceUnfoldrM
377+ , benchFold "intFromTo" toNull sourceIntFromTo
378+
379+ , benchFold "fromList" toNull sourceFromList
380+ ]
381+ , bgroup "elimination"
382+ [ benchFold "toNull" toNull sourceUnfoldrM
383+ , benchFold "mapM_" mapM_ sourceUnfoldrM
384+ , benchFold "uncons" uncons sourceUnfoldrM
385+ , benchFold "foldl'" foldl sourceUnfoldrM
386+ , benchFold "last" last sourceUnfoldrM
387+ ]
388+ , bgroup "nested"
389+ [ benchFold "toNullAp" toNullApNested (sourceUnfoldrMN value2)
390+ , benchFold "toNull" toNullNested (sourceUnfoldrMN value2)
391+ , benchFold "toNull3" toNullNested3 (sourceUnfoldrMN value3)
392+ , benchFold "filterAllIn" filterAllInNested (sourceUnfoldrMN value2)
393+ , benchFold "filterAllOut" filterAllOutNested (sourceUnfoldrMN value2)
394+ , benchFold "toNullApPure" toNullApNested (sourceUnfoldrN value2)
395+ , benchFold "toNullPure" toNullNested (sourceUnfoldrN value2)
396+ , benchFold "toNull3Pure" toNullNested3 (sourceUnfoldrN value3)
397+ , benchFold "filterAllInPure" filterAllInNested (sourceUnfoldrN value2)
398+ , benchFold "filterAllOutPure" filterAllOutNested (sourceUnfoldrN value2)
399+ ]
400+ , bgroup "transformation"
401+ [ benchFold "scan" (scan 1) sourceUnfoldrM
402+ , benchFold "map" (map 1) sourceUnfoldrM
403+ , benchFold "fmap" (fmapD 1) sourceUnfoldrM
404+ , benchFold "mapM" (mapM 1) sourceUnfoldrM
405+ , benchFold "mapMaybe" (mapMaybe 1) sourceUnfoldrM
406+ , benchFold "mapMaybeM" (mapMaybeM 1) sourceUnfoldrM
407+ , benchFold "concatMapNxN" (concatMap 1) (sourceUnfoldrMN value2)
408+ , benchFold "concatMapRepl4xN" concatMapRepl4xN
409+ (sourceUnfoldrMN (value `div` 4))
410+ , benchFold "concatMapPureNxN" (concatMap 1) (sourceUnfoldrN value2)
411+ , benchFold "concatMapURepl4xN" concatMapURepl4xN
412+ (sourceUnfoldrMN (value `div` 4))
413+ ]
414+ , bgroup "transformationX4"
415+ [ benchFold "scan" (scan 4) sourceUnfoldrM
416+ , benchFold "map" (map 4) sourceUnfoldrM
417+ , benchFold "fmap" (fmapD 4) sourceUnfoldrM
418+ , benchFold "mapM" (mapM 4) sourceUnfoldrM
419+ , benchFold "mapMaybe" (mapMaybe 4) sourceUnfoldrM
420+ , benchFold "mapMaybeM" (mapMaybeM 4) sourceUnfoldrM
421+ -- XXX this is horribly slow
422+ -- , benchFold "concatMap" (concatMap 4) (sourceUnfoldrMN value16)
423+ ]
424+ , bgroup "filtering"
425+ [ benchFold "filter-even" (filterEven 1) sourceUnfoldrM
426+ , benchFold "filter-all-out" (filterAllOut 1) sourceUnfoldrM
427+ , benchFold "filter-all-in" (filterAllIn 1) sourceUnfoldrM
428+ , benchFold "take-all" (takeAll 1) sourceUnfoldrM
429+ , benchFold "takeWhile-true" (takeWhileTrue 1) sourceUnfoldrM
430+ , benchFold "drop-one" (dropOne 1) sourceUnfoldrM
431+ , benchFold "drop-all" (dropAll 1) sourceUnfoldrM
432+ , benchFold "dropWhile-true" (dropWhileTrue 1) sourceUnfoldrM
433+ , benchFold "dropWhile-false" (dropWhileFalse 1) sourceUnfoldrM
434+ ]
435+ , bgroup "filteringX4"
436+ [ benchFold "filter-even" (filterEven 4) sourceUnfoldrM
437+ , benchFold "filter-all-out" (filterAllOut 4) sourceUnfoldrM
438+ , benchFold "filter-all-in" (filterAllIn 4) sourceUnfoldrM
439+ , benchFold "take-all" (takeAll 4) sourceUnfoldrM
440+ , benchFold "takeWhile-true" (takeWhileTrue 4) sourceUnfoldrM
441+ , benchFold "drop-one" (dropOne 4) sourceUnfoldrM
442+ , benchFold "drop-all" (dropAll 4) sourceUnfoldrM
443+ , benchFold "dropWhile-true" (dropWhileTrue 4) sourceUnfoldrM
444+ , benchFold "dropWhile-false" (dropWhileFalse 4) sourceUnfoldrM
445+ ]
446+ , bgroup "zipping"
447+ [ benchFold "eqBy" eqBy sourceUnfoldrM
448+ , benchFold "cmpBy" cmpBy sourceUnfoldrM
449+ , benchFold "zip" zip sourceUnfoldrM
450+ ]
451+ , bgroup "mixed"
452+ [ benchFold "scan-map" (scanMap 1) sourceUnfoldrM
453+ , benchFold "drop-map" (dropMap 1) sourceUnfoldrM
454+ , benchFold "drop-scan" (dropScan 1) sourceUnfoldrM
455+ , benchFold "take-drop" (takeDrop 1) sourceUnfoldrM
456+ , benchFold "take-scan" (takeScan 1) sourceUnfoldrM
457+ , benchFold "take-map" (takeMap 1) sourceUnfoldrM
458+ , benchFold "filter-drop" (filterDrop 1) sourceUnfoldrM
459+ , benchFold "filter-take" (filterTake 1) sourceUnfoldrM
460+ , benchFold "filter-scan" (filterScan 1) sourceUnfoldrM
461+ , benchFold "filter-map" (filterMap 1) sourceUnfoldrM
462+ ]
463+ , bgroup "mixedX2"
464+ [ benchFold "scan-map" (scanMap 2) sourceUnfoldrM
465+ , benchFold "drop-map" (dropMap 2) sourceUnfoldrM
466+ , benchFold "drop-scan" (dropScan 2) sourceUnfoldrM
467+ , benchFold "take-drop" (takeDrop 2) sourceUnfoldrM
468+ , benchFold "take-scan" (takeScan 2) sourceUnfoldrM
469+ , benchFold "take-map" (takeMap 2) sourceUnfoldrM
470+ , benchFold "filter-drop" (filterDrop 2) sourceUnfoldrM
471+ , benchFold "filter-take" (filterTake 2) sourceUnfoldrM
472+ , benchFold "filter-scan" (filterScan 2) sourceUnfoldrM
473+ , benchFold "filter-map" (filterMap 2) sourceUnfoldrM
474+ ]
475+ , bgroup "mixedX4"
476+ [ benchFold "scan-map" (scanMap 4) sourceUnfoldrM
477+ , benchFold "drop-map" (dropMap 4) sourceUnfoldrM
478+ , benchFold "drop-scan" (dropScan 4) sourceUnfoldrM
479+ , benchFold "take-drop" (takeDrop 4) sourceUnfoldrM
480+ , benchFold "take-scan" (takeScan 4) sourceUnfoldrM
481+ , benchFold "take-map" (takeMap 4) sourceUnfoldrM
482+ , benchFold "filter-drop" (filterDrop 4) sourceUnfoldrM
483+ , benchFold "filter-take" (filterTake 4) sourceUnfoldrM
484+ , benchFold "filter-scan" (filterScan 4) sourceUnfoldrM
485+ , benchFold "filter-map" (filterMap 4) sourceUnfoldrM
486+ ]
487+ ]
488+ ]
489+
490+-- | Takes a source, and uses it with a default drain/fold method.
491+{-# INLINE benchD #-}
492+benchD :: P.String -> (Int -> Stream P.IO Int) -> Benchmark
493+benchD name f = bench name $ nfIO $ randomRIO (1,1) >>= toNull . f
494+
495+o_n_stack :: [Benchmark]
496+o_n_stack =
497+ [ bgroup "streamD"
498+ [ bgroup "elimination"
499+ [ benchFold "tail" tail sourceUnfoldrM
500+ , benchFold "nullTail" nullTail sourceUnfoldrM
501+ , benchFold "headTail" headTail sourceUnfoldrM
502+ ]
503+ , bgroup "transformation"
504+ [
505+ -- this is horribly slow
506+ -- benchFold "foldrS" (_foldrS 1) sourceUnfoldrM
507+ -- XXX why do these need so much stack
508+ benchFold "intersperse" (intersperse 1) (sourceUnfoldrMN value2)
509+ , benchFold "interspersePure" (intersperse 1) (sourceUnfoldrN value2)
510+ ]
511+ , bgroup "transformationX4"
512+ [
513+ benchFold "intersperse" (intersperse 4) (sourceUnfoldrMN value16)
514+ ]
515+ , bgroup "iterated"
516+ [ benchD "mapM" iterateMapM
517+ , benchD "scan(1/10)" iterateScan
518+ , benchD "filterEven" iterateFilterEven
519+ , benchD "takeAll" iterateTakeAll
520+ , benchD "dropOne" iterateDropOne
521+ , benchD "dropWhileFalse(1/10)" iterateDropWhileFalse
522+ , benchD "dropWhileTrue" iterateDropWhileTrue
523+ , benchD "iterateM" iterateM
524+ ]
525+ ]
526+ ]
527+
528+o_n_space :: [Benchmark]
529+o_n_space =
530+ [ bgroup "streamD"
531+ [ bgroup "elimination"
532+ [ benchFold "toList" toList sourceUnfoldrM
533+ ]
534+ , bgroup "transformation"
535+ [
536+
537+ -- This is horribly slow, never finishes
538+ benchFold "foldlS" (foldlS 1) sourceUnfoldrM
539+ ]
540+ ]
541+ ]
benchmark/Streamly/Benchmark/Data/Stream/StreamDK.hs+38−9
@@ -8,26 +8,35 @@
88{-# LANGUAGE FlexibleContexts #-}
99{-# LANGUAGE ScopedTypeVariables #-}
1010
11−module Streamly.Benchmark.Data.Stream.StreamDK where
11+module Streamly.Benchmark.Data.Stream.StreamDK
12+ (
13+ o_1_space
14+ )
15+where
1216
1317-- import Control.Monad (when)
1418-- import Data.Maybe (isJust)
1519import Prelude
16− (Monad, Int, (+), (.), return, undefined, Maybe(..), round, (/),
17− (**), (>))
18−import qualified Prelude as P
20+ (Monad, Int, (+), return, Maybe(..), (>))
21+-- import qualified Prelude as P
1922-- import qualified Data.List as List
2023
2124import qualified Streamly.Internal.Data.Stream.StreamDK as S
2225-- import qualified Streamly.Internal.Data.Stream.Prelude as SP
2326-- import qualified Streamly.Internal.Data.SVar as S
2427
25−value, value2, value3, value16, maxValue :: Int
28+import Streamly.Benchmark.Common (benchFold)
29+import Gauge (bgroup, Benchmark)
30+
31+value :: Int
2632value = 100000
33+{-
34+value2, value3, value16, maxValue :: Int
2735value2 = round (P.fromIntegral value**(1/2::P.Double)) -- double nested loop
2836value3 = round (P.fromIntegral value**(1/3::P.Double)) -- triple nested loop
2937value16 = round (P.fromIntegral value**(1/16::P.Double)) -- triple nested loop
3038maxValue = value
39+-}
3140
3241-------------------------------------------------------------------------------
3342-- Benchmark ops
@@ -48,6 +57,7 @@ sourceUnfoldr n = S.unfoldr step n
4857 then Nothing
4958 else Just (cnt, cnt + 1)
5059
60+{-
5161{-# INLINE sourceUnfoldrN #-}
5262sourceUnfoldrN :: Monad m => Int -> Int -> Stream m Int
5363sourceUnfoldrN m n = S.unfoldr step n
@@ -56,6 +66,7 @@ sourceUnfoldrN m n = S.unfoldr step n
5666 if cnt > n + m
5767 then Nothing
5868 else Just (cnt, cnt + 1)
69+-}
5970
6071{-# INLINE sourceUnfoldrM #-}
6172sourceUnfoldrM :: Monad m => Int -> Stream m Int
@@ -66,6 +77,7 @@ sourceUnfoldrM n = S.unfoldrM step n
6677 then return Nothing
6778 else return (Just (cnt, cnt + 1))
6879
80+{-
6981{-# INLINE sourceUnfoldrMN #-}
7082sourceUnfoldrMN :: Monad m => Int -> Int -> Stream m Int
7183sourceUnfoldrMN m n = S.unfoldrM step n
@@ -74,6 +86,7 @@ sourceUnfoldrMN m n = S.unfoldrM step n
7486 if cnt > n + m
7587 then return Nothing
7688 else return (Just (cnt, cnt + 1))
89+-}
7790
7891{-
7992{-# INLINE sourceFromEnum #-}
@@ -103,10 +116,6 @@ sourceFoldMapWithM :: Monad m => Int -> Stream m Int
103116sourceFoldMapWithM n = SP.foldMapWith S.serial (S.yieldM . return) [n..n+value]
104117-}
105118
106−{-# INLINE source #-}
107−source :: Monad m => Int -> Stream m Int
108−source = sourceUnfoldrM
109−
110119-------------------------------------------------------------------------------
111120-- Elimination
112121-------------------------------------------------------------------------------
@@ -177,6 +186,7 @@ last = S.last
177186-- Transformation
178187-------------------------------------------------------------------------------
179188
189+{-
180190{-# INLINE transform #-}
181191transform :: Monad m => Stream m a -> m ()
182192transform = runStream
@@ -192,6 +202,7 @@ composeN n f =
192202 3 -> transform . f . f . f
193203 4 -> transform . f . f . f . f
194204 _ -> undefined
205+-}
195206
196207{-
197208{-# INLINE scan #-}
@@ -421,3 +432,21 @@ filterAllInNestedList str = do
421432 then return s
422433 else []
423434-}
435+
436+-------------------------------------------------------------------------------
437+-- Benchmarks
438+-------------------------------------------------------------------------------
439+
440+o_1_space :: [Benchmark]
441+o_1_space =
442+ [ bgroup "streamDK"
443+ [ bgroup "generation"
444+ [ benchFold "unfoldr" toNull sourceUnfoldr
445+ , benchFold "unfoldrM" toNull sourceUnfoldrM
446+ ]
447+ , bgroup "elimination"
448+ [ benchFold "toNull" toNull sourceUnfoldrM
449+ , benchFold "uncons" uncons sourceUnfoldrM
450+ ]
451+ ]
452+ ]
benchmark/Streamly/Benchmark/Data/Stream/StreamK.hs+221−22
@@ -8,14 +8,23 @@
88{-# LANGUAGE FlexibleContexts #-}
99{-# LANGUAGE ScopedTypeVariables #-}
1010
11−module Streamly.Benchmark.Data.Stream.StreamK where
11+module Streamly.Benchmark.Data.Stream.StreamK
12+ (
13+ o_1_space
14+ , o_n_stack
15+ , o_n_heap
16+ , o_n_space
17+ , o_1_space_list
18+ )
19+where
1220
1321import Control.Monad (when)
1422import Data.Maybe (isJust)
1523import Prelude
1624 (Monad, Int, (+), ($), (.), return, even, (>), (<=), div,
1725 subtract, undefined, Maybe(..), not, (>>=),
18− maxBound, flip, (<$>), (<*>), round, (/), (**), (<))
26+ maxBound, flip, (<$>), (<*>), round, (/), (**), (<), foldr, fmap)
27+import System.Random (randomRIO)
1928import qualified Prelude as P
2029import qualified Data.List as List
2130
@@ -23,6 +32,9 @@ import qualified Streamly.Internal.Data.Stream.StreamK as S
2332import qualified Streamly.Internal.Data.Stream.Prelude as SP
2433import qualified Streamly.Internal.Data.SVar as S
2534
35+import Streamly.Benchmark.Common (benchFold)
36+import Gauge (bench, nfIO, bgroup, Benchmark)
37+
2638value, value2, value3, value16, maxValue :: Int
2739value = 100000
2840value2 = round (P.fromIntegral value**(1/2::P.Double)) -- double nested loop
@@ -92,21 +104,14 @@ sourceUnfoldrMN m n = S.unfoldrM step n
92104 then return Nothing
93105 else return (Just (cnt, cnt + 1))
94106
95−{-
96−{-# INLINE sourceFromEnum #-}
97−sourceFromEnum :: Monad m => Int -> Stream m Int
98−sourceFromEnum n = S.enumFromStepN n 1 value
99−-}
100−
101107{-# INLINE sourceFromFoldable #-}
102108sourceFromFoldable :: Int -> Stream m Int
103109sourceFromFoldable n = S.fromFoldable [n..n+value]
104110
105−{-
106111{-# INLINE sourceFromFoldableM #-}
107112sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
108−sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
109−-}
113+sourceFromFoldableM n =
114+ Prelude.foldr S.consM S.nil (Prelude.fmap return [n..n+value])
110115
111116{-# INLINE sourceFoldMapWith #-}
112117sourceFoldMapWith :: Int -> Stream m Int
@@ -116,10 +121,6 @@ sourceFoldMapWith n = SP.foldMapWith S.serial S.yield [n..n+value]
116121sourceFoldMapWithM :: Monad m => Int -> Stream m Int
117122sourceFoldMapWithM n = SP.foldMapWith S.serial (S.yieldM . return) [n..n+value]
118123
119−{-# INLINE source #-}
120−source :: S.MonadAsync m => Int -> Stream m Int
121−source = sourceUnfoldrM
122−
123124-------------------------------------------------------------------------------
124125-- Elimination
125126-------------------------------------------------------------------------------
@@ -184,22 +185,23 @@ composeN n f =
184185
185186{-# INLINE scan #-}
186187{-# INLINE map #-}
187−{-# INLINE fmap #-}
188+{-# INLINE fmapK #-}
188189{-# INLINE filterEven #-}
189190{-# INLINE filterAllOut #-}
190191{-# INLINE filterAllIn #-}
191−{-# INLINE takeOne #-}
192+{-# INLINE _takeOne #-}
192193{-# INLINE takeAll #-}
193194{-# INLINE takeWhileTrue #-}
194195{-# INLINE dropOne #-}
195196{-# INLINE dropAll #-}
196197{-# INLINE dropWhileTrue #-}
197198{-# INLINE dropWhileFalse #-}
199+{-# INLINE foldrS #-}
198200{-# INLINE foldlS #-}
199201{-# INLINE concatMap #-}
200−scan, map, fmap, filterEven, filterAllOut,
201− filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
202− dropWhileTrue, dropWhileFalse, foldlS, concatMap
202+scan, map, fmapK, filterEven, filterAllOut,
203+ filterAllIn, _takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
204+ dropWhileTrue, dropWhileFalse, foldrS, foldlS, concatMap
203205 :: Monad m
204206 => Int -> Stream m Int -> m ()
205207
@@ -211,19 +213,20 @@ mapM, mapMSerial, intersperse
211213
212214scan n = composeN n $ S.scanl' (+) 0
213215map n = composeN n $ P.fmap (+1)
214−fmap n = composeN n $ P.fmap (+1)
216+fmapK n = composeN n $ P.fmap (+1)
215217mapM n = composeN n $ S.mapM return
216218mapMSerial n = composeN n $ S.mapMSerial return
217219filterEven n = composeN n $ S.filter even
218220filterAllOut n = composeN n $ S.filter (> maxValue)
219221filterAllIn n = composeN n $ S.filter (<= maxValue)
220−takeOne n = composeN n $ S.take 1
222+_takeOne n = composeN n $ S.take 1
221223takeAll n = composeN n $ S.take maxValue
222224takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
223225dropOne n = composeN n $ S.drop 1
224226dropAll n = composeN n $ S.drop maxValue
225227dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
226228dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
229+foldrS n = composeN n $ S.foldrS S.cons S.nil
227230foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
228231-- We use a (sqrt n) element stream as source and then concat the same stream
229232-- for each element to produce an n element stream.
@@ -408,3 +411,199 @@ filterAllInNestedList str = do
408411 if s > 0
409412 then return s
410413 else []
414+
415+-------------------------------------------------------------------------------
416+-- Benchmarks
417+-------------------------------------------------------------------------------
418+
419+o_1_space :: [Benchmark]
420+o_1_space =
421+ [ bgroup "streamK"
422+ [ bgroup "generation"
423+ [ benchFold "unfoldr" toNull sourceUnfoldr
424+ , benchFold "unfoldrM" toNull sourceUnfoldrM
425+
426+ , benchFold "fromFoldable" toNull sourceFromFoldable
427+ , benchFold "fromFoldableM" toNull sourceFromFoldableM
428+
429+ -- appends
430+ , benchFold "foldMapWith" toNull sourceFoldMapWith
431+ , benchFold "foldMapWithM" toNull sourceFoldMapWithM
432+ ]
433+ , bgroup "elimination"
434+ [ benchFold "toNull" toNull sourceUnfoldrM
435+ , benchFold "mapM_" mapM_ sourceUnfoldrM
436+ , benchFold "uncons" uncons sourceUnfoldrM
437+ , benchFold "init" init sourceUnfoldrM
438+ , benchFold "foldl'" foldl sourceUnfoldrM
439+ , benchFold "last" last sourceUnfoldrM
440+ ]
441+ , bgroup "nested"
442+ [ benchFold "toNullAp" toNullApNested (sourceUnfoldrMN value2)
443+ , benchFold "toNull" toNullNested (sourceUnfoldrMN value2)
444+ , benchFold "toNull3" toNullNested3 (sourceUnfoldrMN value3)
445+ , benchFold "filterAllIn" filterAllInNested (sourceUnfoldrMN value2)
446+ , benchFold "filterAllOut" filterAllOutNested (sourceUnfoldrMN value2)
447+ , benchFold "toNullApPure" toNullApNested (sourceUnfoldrN value2)
448+ , benchFold "toNullPure" toNullNested (sourceUnfoldrN value2)
449+ , benchFold "toNull3Pure" toNullNested3 (sourceUnfoldrN value3)
450+ , benchFold "filterAllInPure" filterAllInNested (sourceUnfoldrN value2)
451+ , benchFold "filterAllOutPure" filterAllOutNested (sourceUnfoldrN value2)
452+ ]
453+ , bgroup "transformation"
454+ [ benchFold "foldrS" (foldrS 1) sourceUnfoldrM
455+ , benchFold "scan" (scan 1) sourceUnfoldrM
456+ , benchFold "map" (map 1) sourceUnfoldrM
457+ , benchFold "fmap" (fmapK 1) sourceUnfoldrM
458+ , benchFold "mapM" (mapM 1) sourceUnfoldrM
459+ , benchFold "mapMSerial" (mapMSerial 1) sourceUnfoldrM
460+ -- , benchFoldSrcK "concatMap" concatMap
461+ , benchFold "concatMapNxN" (concatMap 1) (sourceUnfoldrMN value2)
462+ , benchFold "concatMapPureNxN" (concatMap 1) (sourceUnfoldrN value2)
463+ , benchFold "concatMapRepl4xN" concatMapRepl4xN
464+ (sourceUnfoldrMN (value `div` 4))
465+ ]
466+ , bgroup "transformationX4"
467+ [ benchFold "scan" (scan 4) sourceUnfoldrM
468+ , benchFold "map" (map 4) sourceUnfoldrM
469+ , benchFold "fmap" (fmapK 4) sourceUnfoldrM
470+ , benchFold "mapM" (mapM 4) sourceUnfoldrM
471+ , benchFold "mapMSerial" (mapMSerial 4) sourceUnfoldrM
472+ -- XXX this is horribly slow
473+ -- , benchFold "concatMap" (concatMap 4) (sourceUnfoldrMN value16)
474+ ]
475+ , bgroup "filtering"
476+ [ benchFold "filter-even" (filterEven 1) sourceUnfoldrM
477+ , benchFold "filter-all-out" (filterAllOut 1) sourceUnfoldrM
478+ , benchFold "filter-all-in" (filterAllIn 1) sourceUnfoldrM
479+ , benchFold "take-all" (takeAll 1) sourceUnfoldrM
480+ , benchFold "takeWhile-true" (takeWhileTrue 1) sourceUnfoldrM
481+ , benchFold "drop-one" (dropOne 1) sourceUnfoldrM
482+ , benchFold "drop-all" (dropAll 1) sourceUnfoldrM
483+ , benchFold "dropWhile-true" (dropWhileTrue 1) sourceUnfoldrM
484+ , benchFold "dropWhile-false" (dropWhileFalse 1) sourceUnfoldrM
485+ ]
486+ , bgroup "filteringX4"
487+ [ benchFold "filter-even" (filterEven 4) sourceUnfoldrM
488+ , benchFold "filter-all-out" (filterAllOut 4) sourceUnfoldrM
489+ , benchFold "filter-all-in" (filterAllIn 4) sourceUnfoldrM
490+ , benchFold "take-all" (takeAll 4) sourceUnfoldrM
491+ , benchFold "takeWhile-true" (takeWhileTrue 4) sourceUnfoldrM
492+ , benchFold "drop-one" (dropOne 4) sourceUnfoldrM
493+ , benchFold "drop-all" (dropAll 4) sourceUnfoldrM
494+ , benchFold "dropWhile-true" (dropWhileTrue 4) sourceUnfoldrM
495+ , benchFold "dropWhile-false" (dropWhileFalse 4) sourceUnfoldrM
496+ ]
497+ , bgroup "zipping"
498+ [ benchFold "zip" zip sourceUnfoldrM
499+ ]
500+ , bgroup "mixed"
501+ [ benchFold "scan-map" (scanMap 1) sourceUnfoldrM
502+ , benchFold "drop-map" (dropMap 1) sourceUnfoldrM
503+ , benchFold "drop-scan" (dropScan 1) sourceUnfoldrM
504+ , benchFold "take-drop" (takeDrop 1) sourceUnfoldrM
505+ , benchFold "take-scan" (takeScan 1) sourceUnfoldrM
506+ , benchFold "take-map" (takeMap 1) sourceUnfoldrM
507+ , benchFold "filter-drop" (filterDrop 1) sourceUnfoldrM
508+ , benchFold "filter-take" (filterTake 1) sourceUnfoldrM
509+ , benchFold "filter-scan" (filterScan 1) sourceUnfoldrM
510+ , benchFold "filter-map" (filterMap 1) sourceUnfoldrM
511+ ]
512+ , bgroup "mixedX2"
513+ [ benchFold "scan-map" (scanMap 2) sourceUnfoldrM
514+ , benchFold "drop-map" (dropMap 2) sourceUnfoldrM
515+ , benchFold "drop-scan" (dropScan 2) sourceUnfoldrM
516+ , benchFold "take-drop" (takeDrop 2) sourceUnfoldrM
517+ , benchFold "take-scan" (takeScan 2) sourceUnfoldrM
518+ , benchFold "take-map" (takeMap 2) sourceUnfoldrM
519+ , benchFold "filter-drop" (filterDrop 2) sourceUnfoldrM
520+ , benchFold "filter-take" (filterTake 2) sourceUnfoldrM
521+ , benchFold "filter-scan" (filterScan 2) sourceUnfoldrM
522+ , benchFold "filter-map" (filterMap 2) sourceUnfoldrM
523+ ]
524+ , bgroup "mixedX4"
525+ [ benchFold "scan-map" (scanMap 4) sourceUnfoldrM
526+ , benchFold "drop-map" (dropMap 4) sourceUnfoldrM
527+ , benchFold "drop-scan" (dropScan 4) sourceUnfoldrM
528+ , benchFold "take-drop" (takeDrop 4) sourceUnfoldrM
529+ , benchFold "take-scan" (takeScan 4) sourceUnfoldrM
530+ , benchFold "take-map" (takeMap 4) sourceUnfoldrM
531+ , benchFold "filter-drop" (filterDrop 4) sourceUnfoldrM
532+ , benchFold "filter-take" (filterTake 4) sourceUnfoldrM
533+ , benchFold "filter-scan" (filterScan 4) sourceUnfoldrM
534+ , benchFold "filter-map" (filterMap 4) sourceUnfoldrM
535+ ]
536+ ]
537+ ]
538+
539+o_n_heap :: [Benchmark]
540+o_n_heap =
541+ [ bgroup "streamK"
542+ [ bgroup "transformation"
543+ [ benchFold "foldlS" (foldlS 1) sourceUnfoldrM
544+ ]
545+ ]
546+ ]
547+
548+{-# INLINE benchK #-}
549+benchK :: P.String -> (Int -> Stream P.IO Int) -> Benchmark
550+benchK name f = bench name $ nfIO $ randomRIO (1,1) >>= toNull . f
551+
552+o_n_stack :: [Benchmark]
553+o_n_stack =
554+ [ bgroup "streamK"
555+ [ bgroup "elimination"
556+ [ benchFold "tail" tail sourceUnfoldrM
557+ , benchFold "nullTail" nullTail sourceUnfoldrM
558+ , benchFold "headTail" headTail sourceUnfoldrM
559+ ]
560+ , bgroup "transformation"
561+ [
562+ -- XXX why do these need so much stack
563+ benchFold "intersperse" (intersperse 1) (sourceUnfoldrMN value2)
564+ , benchFold "interspersePure" (intersperse 1) (sourceUnfoldrN value2)
565+ ]
566+ , bgroup "transformationX4"
567+ [
568+ benchFold "intersperse" (intersperse 4) (sourceUnfoldrMN value16)
569+ ]
570+ , bgroup "iterated"
571+ [ benchK "mapM" iterateMapM
572+ , benchK "scan(1/10)" iterateScan
573+ , benchK "filterEven" iterateFilterEven
574+ , benchK "takeAll" iterateTakeAll
575+ , benchK "dropOne" iterateDropOne
576+ , benchK "dropWhileFalse(1/10)" iterateDropWhileFalse
577+ , benchK "dropWhileTrue" iterateDropWhileTrue
578+ ]
579+ ]
580+ ]
581+
582+o_n_space :: [Benchmark]
583+o_n_space =
584+ [ bgroup "streamK"
585+ [ bgroup "elimination"
586+ [ benchFold "toList" toList sourceUnfoldrM
587+ ]
588+ ]
589+ ]
590+
591+{-# INLINE benchList #-}
592+benchList :: P.String -> ([Int] -> [Int]) -> (Int -> [Int]) -> Benchmark
593+benchList name run f = bench name $ nfIO $ randomRIO (1,1) >>= return . run . f
594+
595+o_1_space_list :: [Benchmark]
596+o_1_space_list =
597+ [ bgroup "list"
598+ [ bgroup "elimination"
599+ [ benchList "last" (\xs -> [List.last xs]) (sourceUnfoldrList value)
600+ ]
601+ , bgroup "nested"
602+ [ benchList "toNullAp" toNullApNestedList (sourceUnfoldrList value2)
603+ , benchList "toNull" toNullNestedList (sourceUnfoldrList value2)
604+ , benchList "toNull3" toNullNestedList3 (sourceUnfoldrList value3)
605+ , benchList "filterAllIn" filterAllInNestedList (sourceUnfoldrList value2)
606+ , benchList "filterAllOut" filterAllOutNestedList (sourceUnfoldrList value2)
607+ ]
608+ ]
609+ ]
benchmark/lib/Streamly/Benchmark/Common.hs+8
@@ -16,6 +16,7 @@ module Streamly.Benchmark.Common
1616 , benchIOSink1
1717 , benchPure
1818 , benchPureSink1
19+ , benchFold
1920
2021 , benchIOSrc1
2122 , benchPureSrc
@@ -64,6 +65,13 @@ benchIOSink1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
6465benchIOSrc1 :: String -> (Int -> IO ()) -> Benchmark
6566benchIOSrc1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
6667
68+-- We need a monadic bind here to make sure that the function f does not get
69+-- completely optimized out by the compiler in some cases.
70+{-# INLINE benchFold #-}
71+benchFold :: NFData b
72+ => String -> (t IO Int -> IO b) -> (Int -> t IO Int) -> Benchmark
73+benchFold name f src = bench name $ nfIO $ randomRIO (1,1) >>= f . src
74+
6775{-# INLINE benchPure #-}
6876benchPure :: NFData b => String -> (Int -> a) -> (a -> b) -> Benchmark
6977benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
benchmark/streamly-benchmarks.cabal+41−9
@@ -131,7 +131,12 @@ library
131131 hs-source-dirs: lib
132132 exposed-modules:
133133 Streamly.Benchmark.Common
134− , Streamly.Benchmark.Prelude
134+
135+library lib-prelude
136+ import: lib-options, bench-depends
137+ hs-source-dirs: lib
138+ exposed-modules:
139+ Streamly.Benchmark.Prelude
135140
136141-------------------------------------------------------------------------------
137142-- Benchmarks
@@ -145,7 +150,6 @@ common bench-options
145150 import: compile-options, optimization-options, bench-depends
146151 ghc-options: -with-rtsopts "-T -K32K -M16M"
147152 build-depends: streamly-benchmarks
148− hs-source-dirs: .
149153
150154-- Some benchmarks are threaded some are not
151155common bench-options-threaded
@@ -154,7 +158,6 @@ common bench-options-threaded
154158 -- trigger only with these options.
155159 ghc-options: -threaded -with-rtsopts "-T -N2 -K32K -M16M"
156160 build-depends: streamly-benchmarks
157− hs-source-dirs: .
158161
159162-- XXX the individual modules can just export a bunch of gauge Benchmark
160163-- grouped by space usage and then we can combine the groups in just four
@@ -169,27 +172,35 @@ benchmark linear
169172 import: bench-options
170173 type: exitcode-stdio-1.0
171174 ghc-options: -with-rtsopts "-T -K36K -M16M"
172− main-is: Streamly/Benchmark/Prelude/Serial/O_1_Space.hs
175+ hs-source-dirs: ., Streamly/Benchmark/Prelude/Serial
176+ main-is: O_1_Space.hs
173177 other-modules: NestedOps, NestedUnfoldOps
178+ build-depends: lib-prelude
174179
175180benchmark serial-o-n-heap
176181 import: bench-options
177182 type: exitcode-stdio-1.0
178183 ghc-options: -with-rtsopts "-T -K36K -M128M"
179− main-is: Streamly/Benchmark/Prelude/Serial/O_n_Heap.hs
184+ hs-source-dirs: Streamly/Benchmark/Prelude/Serial
185+ main-is: O_n_Heap.hs
186+ build-depends: lib-prelude
180187
181188benchmark serial-o-n-stack
182189 import: bench-options
183190 type: exitcode-stdio-1.0
184191 ghc-options: -with-rtsopts "-T -K1M -M16M"
185− main-is: Streamly/Benchmark/Prelude/Serial/O_n_Stack.hs
192+ hs-source-dirs: Streamly/Benchmark/Prelude/Serial
193+ main-is: O_n_Stack.hs
194+ build-depends: lib-prelude
186195
187196benchmark serial-o-n-space
188197 import: bench-options
189198 type: exitcode-stdio-1.0
190199 ghc-options: -with-rtsopts "-T -K16M -M64M"
191− main-is: Streamly/Benchmark/Prelude/Serial/O_n_Space.hs
200+ hs-source-dirs: ., Streamly/Benchmark/Prelude/Serial
201+ main-is: O_n_Space.hs
192202 other-modules: NestedOps, NestedUnfoldOps
203+ build-depends: lib-prelude
193204
194205-------------------------------------------------------------------------------
195206-- Raw Streams
@@ -197,11 +208,12 @@ benchmark serial-o-n-space
197208
198209library lib-base
199210 import: lib-options, bench-depends
200− hs-source-dirs: ., lib
211+ hs-source-dirs: .
201212 exposed-modules:
202213 Streamly.Benchmark.Data.Stream.StreamD
203214 , Streamly.Benchmark.Data.Stream.StreamK
204215 , Streamly.Benchmark.Data.Stream.StreamDK
216+ build-depends: streamly-benchmarks
205217
206218benchmark base
207219-- benchmark base-o-1-space
@@ -209,6 +221,7 @@ benchmark base
209221 type: exitcode-stdio-1.0
210222 cpp-options: -DO_1_SPACE
211223 ghc-options: -with-rtsopts "-T -K36K -M16M"
224+ hs-source-dirs: Streamly/Benchmark/Data/Stream
212225 main-is: BaseStreams.hs
213226 build-depends: lib-base
214227
@@ -217,6 +230,7 @@ benchmark base-o-n-heap
217230 type: exitcode-stdio-1.0
218231 cpp-options: -DO_N_HEAP
219232 ghc-options: -with-rtsopts "-T -K36K -M64M"
233+ hs-source-dirs: Streamly/Benchmark/Data/Stream
220234 main-is: BaseStreams.hs
221235 build-depends: lib-base
222236
@@ -225,6 +239,7 @@ benchmark base-o-n-stack
225239 type: exitcode-stdio-1.0
226240 cpp-options: -DO_N_STACK
227241 ghc-options: -with-rtsopts "-T -K1M -M16M"
242+ hs-source-dirs: Streamly/Benchmark/Data/Stream
228243 main-is: BaseStreams.hs
229244 build-depends: lib-base
230245
@@ -232,12 +247,14 @@ benchmark base-o-n-space
232247 import: bench-options
233248 type: exitcode-stdio-1.0
234249 cpp-options: -DO_N_SPACE
235− ghc-options: -with-rtsopts "-T -K2M -M32M"
250+ ghc-options: -with-rtsopts "-T -K32M -M32M"
251+ hs-source-dirs: Streamly/Benchmark/Data/Stream
236252 main-is: BaseStreams.hs
237253 build-depends: lib-base
238254
239255executable nano-bench
240256 import: bench-options
257+ hs-source-dirs: .
241258 main-is: NanoBenchmarks.hs
242259 if flag(dev)
243260 buildable: True
@@ -252,13 +269,16 @@ benchmark linear-async
252269 import: bench-options-threaded
253270 type: exitcode-stdio-1.0
254271 ghc-options: -with-rtsopts "-T -N2 -K64K -M16M"
272+ hs-source-dirs: .
255273 main-is: LinearAsync.hs
274+ build-depends: lib-prelude
256275
257276benchmark nested-concurrent
258277 import: bench-options-threaded
259278 type: exitcode-stdio-1.0
260279 -- XXX this can be lowered once we split out the finite benchmarks
261280 ghc-options: -with-rtsopts "-T -N2 -K256K -M128M"
281+ hs-source-dirs: .
262282 main-is: NestedConcurrent.hs
263283 other-modules: NestedOps
264284
@@ -266,24 +286,30 @@ benchmark parallel
266286 import: bench-options-threaded
267287 type: exitcode-stdio-1.0
268288 ghc-options: -with-rtsopts "-T -N2 -K128K -M256M"
289+ hs-source-dirs: .
269290 main-is: Parallel.hs
270291 other-modules: NestedOps
292+ build-depends: lib-prelude
271293
272294benchmark concurrent
273295 import: bench-options-threaded
274296 type: exitcode-stdio-1.0
297+ hs-source-dirs: .
275298 main-is: Concurrent.hs
276299 ghc-options: -with-rtsopts "-T -N2 -K256K -M384M"
277300
278301benchmark adaptive
279302 import: bench-options-threaded
280303 type: exitcode-stdio-1.0
304+ hs-source-dirs: .
281305 main-is: Adaptive.hs
282306
283307benchmark linear-rate
284308 import: bench-options-threaded
285309 type: exitcode-stdio-1.0
310+ hs-source-dirs: .
286311 main-is: LinearRate.hs
312+ build-depends: lib-prelude
287313
288314-------------------------------------------------------------------------------
289315-- Array Benchmarks
@@ -293,6 +319,7 @@ benchmark unpinned-array
293319 import: bench-options
294320 type: exitcode-stdio-1.0
295321 ghc-options: -with-rtsopts "-T -K1K -M128M"
322+ hs-source-dirs: .
296323 main-is: Streamly/Benchmark/Data/Array.hs
297324 other-modules: Streamly.Benchmark.Data.ArrayOps
298325
@@ -300,6 +327,7 @@ benchmark prim-array
300327 import: bench-options
301328 type: exitcode-stdio-1.0
302329 ghc-options: -with-rtsopts "-T -K64K -M32M"
330+ hs-source-dirs: .
303331 main-is: Streamly/Benchmark/Data/Prim/Array.hs
304332 other-modules: Streamly.Benchmark.Data.Prim.ArrayOps
305333
@@ -307,6 +335,7 @@ benchmark small-array
307335 import: bench-options
308336 type: exitcode-stdio-1.0
309337 ghc-options: -with-rtsopts "-T -K128K -M16M"
338+ hs-source-dirs: .
310339 main-is: Streamly/Benchmark/Data/SmallArray.hs
311340 other-modules: Streamly.Benchmark.Data.SmallArrayOps
312341
@@ -314,6 +343,7 @@ benchmark array
314343 import: bench-options
315344 type: exitcode-stdio-1.0
316345 ghc-options: -with-rtsopts "-T -K64K -M128M"
346+ hs-source-dirs: .
317347 main-is: Array.hs
318348 other-modules: ArrayOps
319349
@@ -324,6 +354,7 @@ benchmark array
324354benchmark fileio
325355 import: bench-options
326356 type: exitcode-stdio-1.0
357+ hs-source-dirs: .
327358 main-is: FileIO.hs
328359 other-modules: Streamly.Benchmark.FileIO.Array
329360 , Streamly.Benchmark.FileIO.Stream
@@ -337,6 +368,7 @@ benchmark fileio
337368executable chart
338369 default-language: Haskell2010
339370 ghc-options: -Wall
371+ hs-source-dirs: .
340372 main-is: Chart.hs
341373 if flag(dev) && !flag(no-charts) && !impl(ghcjs)
342374 buildable: True
streamly.cabal+1
@@ -125,6 +125,7 @@ extra-source-files:
125125 benchmark/lib/Streamly/Benchmark/*.hs
126126 benchmark/Streamly/Benchmark/Data/*.hs
127127 benchmark/Streamly/Benchmark/Data/Prim/*.hs
128+ benchmark/Streamly/Benchmark/Data/Stream/*.hs
128129 benchmark/Streamly/Benchmark/FileIO/*.hs
129130 benchmark/Streamly/Benchmark/Prelude/Serial/*.hs
130131