on 290d2f6 help sign in
streamly/benchmark/Linear.hs
486 lines 23 kB history raw
1{-# LANGUAGE CPP #-}
2#if __GLASGOW_HASKELL__ >= 800
3{-# OPTIONS_GHC -Wno-orphans #-}
4#endif
6-- |
7-- Module : Main
8-- Copyright : (c) 2018 Harendra Kumar
9--
10-- License : BSD3
11-- Maintainer : streamly@composewell.com
13import Control.DeepSeq (NFData(..), deepseq)
14import Data.Functor.Identity (Identity, runIdentity)
15import Data.Monoid (Last(..))
16import System.Random (randomRIO)
18import Common (parseCLIOpts)
20import qualified GHC.Exts as GHC
21import qualified Streamly.Benchmark.Prelude as Ops
23import Streamly
24import qualified Streamly.Data.Fold as FL
25import qualified Streamly.Memory.Array as A
26import qualified Streamly.Prelude as S
27import qualified Streamly.Internal.Data.Sink as Sink
29import Streamly.Internal.Data.Time.Units
30import qualified Streamly.Internal.Memory.Array as IA
31import qualified Streamly.Internal.Data.Fold as IFL
32import qualified Streamly.Internal.Prelude as IP
33import qualified Streamly.Internal.Data.Pipe as Pipe
35import Gauge
37-------------------------------------------------------------------------------
38--
39-------------------------------------------------------------------------------
41#if !MIN_VERSION_deepseq(1,4,3)
42instance NFData Ordering where rnf = (`seq` ())
43#endif
45-- We need a monadic bind here to make sure that the function f does not get
46-- completely optimized out by the compiler in some cases.
48-- | Takes a fold method, and uses it with a default source.
49{-# INLINE benchIOSink #-}
50benchIOSink
51 :: (IsStream t, NFData b)
52 => Int -> String -> (t IO Int -> IO b) -> Benchmark
53benchIOSink value name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source value
55{-# INLINE benchHoistSink #-}
56benchHoistSink
57 :: (IsStream t, NFData b)
58 => Int -> String -> (t Identity Int -> IO b) -> Benchmark
59benchHoistSink value name f =
60 bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.sourceUnfoldr value
62-- XXX once we convert all the functions to use this we can rename this to
63-- benchIOSink
64{-# INLINE benchIOSink1 #-}
65benchIOSink1 :: NFData b => String -> (Int -> IO b) -> Benchmark
66benchIOSink1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
68-- XXX We should be using sourceUnfoldrM for fair comparison with IO monad, but
69-- we can't use it as it requires MonadAsync constraint.
70{-# INLINE benchIdentitySink #-}
71benchIdentitySink
72 :: (IsStream t, NFData b)
73 => Int -> String -> (t Identity Int -> Identity b) -> Benchmark
74benchIdentitySink value name f = bench name $ nf (f . Ops.sourceUnfoldr value) 1
76-- | Takes a source, and uses it with a default drain/fold method.
77{-# INLINE benchIOSrc #-}
78benchIOSrc
79 :: (t IO a -> SerialT IO a)
80 -> String
81 -> (Int -> t IO a)
82 -> Benchmark
83benchIOSrc t name f =
84 bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
86{-# INLINE benchIOSrc1 #-}
87benchIOSrc1 :: String -> (Int -> IO ()) -> Benchmark
88benchIOSrc1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
90{-# INLINE benchPure #-}
91benchPure :: NFData b => String -> (Int -> a) -> (a -> b) -> Benchmark
92benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
94{-# INLINE benchPureSink #-}
95benchPureSink :: NFData b => Int -> String -> (SerialT Identity Int -> b) -> Benchmark
96benchPureSink value name f = benchPure name (Ops.sourceUnfoldr value) f
98-- XXX once we convert all the functions to use this we can rename this to
99-- benchPureSink
100{-# INLINE benchPureSink1 #-}
101benchPureSink1 :: NFData b => String -> (Int -> Identity b) -> Benchmark
102benchPureSink1 name f =
103 bench name $ nfIO $ randomRIO (1,1) >>= return . runIdentity . f
105{-# INLINE benchPureSinkIO #-}
106benchPureSinkIO
107 :: NFData b
108 => Int -> String -> (SerialT Identity Int -> IO b) -> Benchmark
109benchPureSinkIO value name f =
110 bench name $ nfIO $ randomRIO (1, 1) >>= f . Ops.sourceUnfoldr value
112{-# INLINE benchPureSrc #-}
113benchPureSrc :: String -> (Int -> SerialT Identity a) -> Benchmark
114benchPureSrc name src = benchPure name src (runIdentity . S.drain)
116mkString :: Int -> String
117mkString value = "fromList [1" ++ concat (replicate value ",1") ++ "]"
119mkListString :: Int -> String
120mkListString value = "[1" ++ concat (replicate value ",1") ++ "]"
122mkList :: Int -> [Int]
123mkList value = [1..value]
125defaultStreamSize :: Int
126defaultStreamSize = 100000
128main :: IO ()
129main = do
130 -- XXX Fix indentation
131 (value, cfg, benches) <- parseCLIOpts defaultStreamSize
132 value `seq` runMode (mode cfg) cfg benches
133 [ bgroup "serially"
134 [ bgroup "pure"
135 [ benchPureSink value "id" id
136 , benchPureSink1 "eqBy" (Ops.eqByPure value)
137 , benchPureSink value "==" Ops.eqInstance
138 , benchPureSink value "/=" Ops.eqInstanceNotEq
139 , benchPureSink1 "cmpBy" (Ops.cmpByPure value)
140 , benchPureSink value "<" Ops.ordInstance
141 , benchPureSink value "min" Ops.ordInstanceMin
142 , benchPureSrc "IsList.fromList" (Ops.sourceIsList value)
143 -- length is used to check for foldr/build fusion
144 , benchPureSink value "length . IsList.toList" (length . GHC.toList)
145 , benchPureSrc "IsString.fromString" (Ops.sourceIsString value)
146 , mkString value `deepseq` (bench "readsPrec pure streams" $
147 nf Ops.readInstance (mkString value))
148 , mkString value `deepseq` (bench "readsPrec Haskell lists" $
149 nf Ops.readInstanceList (mkListString value))
150 , benchPureSink value "showsPrec pure streams" Ops.showInstance
151 , mkList value `deepseq` (bench "showPrec Haskell lists" $
152 nf Ops.showInstanceList (mkList value))
153 , benchPureSink value "foldl'" Ops.pureFoldl'
154 , benchPureSink value "foldable/foldl'" Ops.foldableFoldl'
155 , benchPureSink value "foldable/sum" Ops.foldableSum
156 , benchPureSinkIO value "traversable/mapM" Ops.traversableMapM
157 ]
158 , bgroup "generation"
159 [ -- Most basic, barely stream continuations running
160 benchIOSrc serially "unfoldr" (Ops.sourceUnfoldr value)
161 , benchIOSrc serially "unfoldrM" (Ops.sourceUnfoldrM value)
162 , benchIOSrc serially "intFromTo" (Ops.sourceIntFromTo value)
163 , benchIOSrc serially "intFromThenTo" (Ops.sourceIntFromThenTo value)
164 , benchIOSrc serially "integerFromStep" (Ops.sourceIntegerFromStep value)
165 , benchIOSrc serially "fracFromThenTo" (Ops.sourceFracFromThenTo value)
166 , benchIOSrc serially "fracFromTo" (Ops.sourceFracFromTo value)
167 , benchIOSrc serially "fromList" (Ops.sourceFromList value)
168 , benchIOSrc serially "fromListM" (Ops.sourceFromListM value)
169 -- These are essentially cons and consM
170 , benchIOSrc serially "fromFoldable" (Ops.sourceFromFoldable value)
171 , benchIOSrc serially "fromFoldableM" (Ops.sourceFromFoldableM value)
172 ]
173 , bgroup "elimination"
174 [ bgroup "reduce"
175 [ bgroup "IO"
176 [ benchIOSink value "foldrM" Ops.foldrMReduce
177 , benchIOSink value "foldl'" Ops.foldl'Reduce
178 , benchIOSink value "foldl1'" Ops.foldl1'Reduce
179 , benchIOSink value "foldlM'" Ops.foldlM'Reduce
180 ]
181 , bgroup "Identity"
182 [ benchIdentitySink value "foldrM" Ops.foldrMReduce
183 , benchIdentitySink value "foldl'" Ops.foldl'Reduce
184 , benchIdentitySink value "foldl1'" Ops.foldl1'Reduce
185 , benchIdentitySink value "foldlM'" Ops.foldlM'Reduce
186 ]
187 ]
189 , bgroup "build"
190 [ bgroup "IO"
191 [ benchIOSink value "foldrM" Ops.foldrMBuild
192 , benchIOSink value "foldl'" Ops.foldl'Build
193 , benchIOSink value "foldlM'" Ops.foldlM'Build
194 ]
195 , bgroup "Identity"
196 [ benchIdentitySink value "foldrM" Ops.foldrMBuild
197 , benchIdentitySink value "foldl'" Ops.foldl'Build
198 , benchIdentitySink value "foldlM'" Ops.foldlM'Build
199 ]
200 ]
201 , benchIOSink value "uncons" Ops.uncons
202 , benchIOSink value "toNull" $ Ops.toNull serially
203 , benchIOSink value "mapM_" Ops.mapM_
205 , benchIOSink value "init" Ops.init
206 , benchIOSink value "tail" Ops.tail
207 , benchIOSink value "nullHeadTail" Ops.nullHeadTail
209 -- this is too low and causes all benchmarks reported in ns
210 -- , benchIOSink value "head" Ops.head
211 , benchIOSink value "last" Ops.last
212 -- , benchIOSink value "lookup" Ops.lookup
213 , benchIOSink value "find" (Ops.find value)
214 , benchIOSink value "findIndex" (Ops.findIndex value)
215 , benchIOSink value "elemIndex" (Ops.elemIndex value)
217 -- this is too low and causes all benchmarks reported in ns
218 -- , benchIOSink value "null" Ops.null
219 , benchIOSink value "elem" (Ops.elem value)
220 , benchIOSink value "notElem" (Ops.notElem value)
221 , benchIOSink value "all" (Ops.all value)
222 , benchIOSink value "any" (Ops.any value)
223 , benchIOSink value "and" (Ops.and value)
224 , benchIOSink value "or" (Ops.or value)
226 , benchIOSink value "length" Ops.length
227 , benchHoistSink value "length . generally" (Ops.length . IP.generally)
228 , benchIOSink value "sum" Ops.sum
229 , benchIOSink value "product" Ops.product
231 , benchIOSink value "maximumBy" Ops.maximumBy
232 , benchIOSink value "maximum" Ops.maximum
233 , benchIOSink value "minimumBy" Ops.minimumBy
234 , benchIOSink value "minimum" Ops.minimum
236 , benchIOSink value "toList" Ops.toList
237 , benchIOSink value "toListRev" Ops.toListRev
238 ]
239 , bgroup "folds"
240 [ benchIOSink value "drain" (S.fold FL.drain)
241 , benchIOSink value "drainN" (S.fold (IFL.drainN value))
242 , benchIOSink value "drainWhileTrue" (S.fold (IFL.drainWhile $ (<=) (value + 1)))
243 , benchIOSink value "drainWhileFalse" (S.fold (IFL.drainWhile $ (>=) (value + 1)))
244 , benchIOSink value "sink" (S.fold $ Sink.toFold Sink.drain)
245 , benchIOSink value "last" (S.fold FL.last)
246 , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
247 , benchIOSink value "lastN.10" (S.fold (IA.lastN 10))
248 , benchIOSink value "lastN.Max" (S.fold (IA.lastN (value + 1)))
249 , benchIOSink value "length" (S.fold FL.length)
250 , benchIOSink value "sum" (S.fold FL.sum)
251 , benchIOSink value "product" (S.fold FL.product)
252 , benchIOSink value "maximumBy" (S.fold (FL.maximumBy compare))
253 , benchIOSink value "maximum" (S.fold FL.maximum)
254 , benchIOSink value "minimumBy" (S.fold (FL.minimumBy compare))
255 , benchIOSink value "minimum" (S.fold FL.minimum)
256 , benchIOSink value "mean" (\s -> S.fold FL.mean (S.map (fromIntegral :: Int -> Double) s))
257 , benchIOSink value "variance" (\s -> S.fold FL.variance (S.map (fromIntegral :: Int -> Double) s))
258 , benchIOSink value "stdDev" (\s -> S.fold FL.stdDev (S.map (fromIntegral :: Int -> Double) s))
260 , benchIOSink value "mconcat" (S.fold FL.mconcat . (S.map (Last . Just)))
261 , benchIOSink value "foldMap" (S.fold (FL.foldMap (Last . Just)))
263 , benchIOSink value "toList" (S.fold FL.toList)
264 , benchIOSink value "toListRevF" (S.fold IFL.toListRevF)
265 , benchIOSink value "toStream" (S.fold IP.toStream)
266 , benchIOSink value "toStreamRev" (S.fold IP.toStreamRev)
267 , benchIOSink value "writeN" (S.fold (A.writeN value))
269 , benchIOSink value "index" (S.fold (FL.index (value + 1)))
270 , benchIOSink value "head" (S.fold FL.head)
271 , benchIOSink value "find" (S.fold (FL.find (== (value + 1))))
272 , benchIOSink value "findIndex" (S.fold (FL.findIndex (== (value + 1))))
273 , benchIOSink value "elemIndex" (S.fold (FL.elemIndex (value + 1)))
275 , benchIOSink value "null" (S.fold FL.null)
276 , benchIOSink value "elem" (S.fold (FL.elem (value + 1)))
277 , benchIOSink value "notElem" (S.fold (FL.notElem (value + 1)))
278 , benchIOSink value "all" (S.fold (FL.all (<= (value + 1))))
279 , benchIOSink value "any" (S.fold (FL.any (> (value + 1))))
280 , benchIOSink value "and" (\s -> S.fold FL.and (S.map (<= (value + 1)) s))
281 , benchIOSink value "or" (\s -> S.fold FL.or (S.map (> (value + 1)) s))
282 ]
283 , bgroup "fold-multi-stream"
284 [ benchIOSink1 "eqBy" (Ops.eqBy value)
285 , benchIOSink1 "cmpBy" (Ops.cmpBy value)
286 , benchIOSink value "isPrefixOf" Ops.isPrefixOf
287 , benchIOSink value "isSubsequenceOf" Ops.isSubsequenceOf
288 , benchIOSink value "stripPrefix" Ops.stripPrefix
289 ]
290 , bgroup "folds-transforms"
291 [ benchIOSink value "drain" (S.fold FL.drain)
292 , benchIOSink value "lmap" (S.fold (IFL.lmap (+1) FL.drain))
293 , benchIOSink value "pipe-mapM"
294 (S.fold (IFL.transform (Pipe.mapM (\x -> return $ x + 1)) FL.drain))
295 ]
296 , bgroup "folds-compositions" -- Applicative
297 [
298 benchIOSink value "all,any" (S.fold ((,) <$> FL.all (<= (value + 1))
299 <*> FL.any (> (value + 1))))
300 , benchIOSink value "sum,length" (S.fold ((,) <$> FL.sum <*> FL.length))
301 ]
302 , bgroup "pipes"
303 [ benchIOSink value "mapM" (Ops.transformMapM serially 1)
304 , benchIOSink value "compose" (Ops.transformComposeMapM serially 1)
305 , benchIOSink value "tee" (Ops.transformTeeMapM serially 1)
306 , benchIOSink value "zip" (Ops.transformZipMapM serially 1)
307 ]
308 , bgroup "pipesX4"
309 [ benchIOSink value "mapM" (Ops.transformMapM serially 4)
310 , benchIOSink value "compose" (Ops.transformComposeMapM serially 4)
311 , benchIOSink value "tee" (Ops.transformTeeMapM serially 4)
312 , benchIOSink value "zip" (Ops.transformZipMapM serially 4)
313 ]
314 , bgroup "transformer"
315 [ benchIOSrc serially "evalState" (Ops.evalStateT value)
316 , benchIOSrc serially "withState" (Ops.withState value)
317 ]
318 , bgroup "transformation"
319 [ benchIOSink value "scanl" (Ops.scan 1)
320 , benchIOSink value "scanl1'" (Ops.scanl1' 1)
321 , benchIOSink value "map" (Ops.map 1)
322 , benchIOSink value "fmap" (Ops.fmap 1)
323 , benchIOSink value "mapM" (Ops.mapM serially 1)
324 , benchIOSink value "mapMaybe" (Ops.mapMaybe 1)
325 , benchIOSink value "mapMaybeM" (Ops.mapMaybeM 1)
326 , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
327 Ops.sequence serially (Ops.sourceUnfoldrMAction value n)
328 , benchIOSink value "findIndices" (Ops.findIndices value 1)
329 , benchIOSink value "elemIndices" (Ops.elemIndices value 1)
330 , benchIOSink value "reverse" (Ops.reverse 1)
331 , benchIOSink value "reverse'" (Ops.reverse' 1)
332 , benchIOSink value "foldrS" (Ops.foldrS 1)
333 , benchIOSink value "foldrSMap" (Ops.foldrSMap 1)
334 , benchIOSink value "foldrT" (Ops.foldrT 1)
335 , benchIOSink value "foldrTMap" (Ops.foldrTMap 1)
336 , benchIOSink value "tap" (Ops.tap 1)
337 , benchIOSink value "tapRate 1 second" (Ops.tapRate 1)
338 , benchIOSink value "pollCounts 1 second" (Ops.pollCounts 1)
339 , benchIOSink value "tapAsync" (Ops.tapAsync 1)
340 , benchIOSink value "tapAsyncS" (Ops.tapAsyncS 1)
341 ]
342 , bgroup "transformationX4"
343 [ benchIOSink value "scan" (Ops.scan 4)
344 , benchIOSink value "scanl1'" (Ops.scanl1' 4)
345 , benchIOSink value "map" (Ops.map 4)
346 , benchIOSink value "fmap" (Ops.fmap 4)
347 , benchIOSink value "mapM" (Ops.mapM serially 4)
348 , benchIOSink value "mapMaybe" (Ops.mapMaybe 4)
349 , benchIOSink value "mapMaybeM" (Ops.mapMaybeM 4)
350 -- , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
351 -- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
352 , benchIOSink value "findIndices" (Ops.findIndices value 4)
353 , benchIOSink value "elemIndices" (Ops.elemIndices value 4)
354 ]
355 , bgroup "filtering"
356 [ benchIOSink value "filter-even" (Ops.filterEven 1)
357 , benchIOSink value "filter-all-out" (Ops.filterAllOut value 1)
358 , benchIOSink value "filter-all-in" (Ops.filterAllIn value 1)
360 , benchIOSink value "take-all" (Ops.takeAll value 1)
361 , benchIOSink value "takeByTime-all"
362 (Ops.takeByTime (NanoSecond64 maxBound) 1)
363 , benchIOSink value "takeWhile-true" (Ops.takeWhileTrue value 1)
364 --, benchIOSink value "takeWhileM-true" (Ops.takeWhileMTrue 1)
366 -- "drop-one" is dual to "last"
367 , benchIOSink value "drop-one" (Ops.dropOne 1)
368 , benchIOSink value "drop-all" (Ops.dropAll value 1)
369 , benchIOSink value "dropByTime-all"
370 (Ops.dropByTime (NanoSecond64 maxBound) 1)
371 , benchIOSink value "dropWhile-true" (Ops.dropWhileTrue value 1)
372 --, benchIOSink value "dropWhileM-true" (Ops.dropWhileMTrue 1)
373 , benchIOSink value "dropWhile-false" (Ops.dropWhileFalse value 1)
375 , benchIOSink value "deleteBy" (Ops.deleteBy value 1)
376 , benchIOSink value "intersperse" (Ops.intersperse value 1)
377 , benchIOSink value "insertBy" (Ops.insertBy value 1)
378 ]
379 , bgroup "filteringX4"
380 [ benchIOSink value "filter-even" (Ops.filterEven 4)
381 , benchIOSink value "filter-all-out" (Ops.filterAllOut value 4)
382 , benchIOSink value "filter-all-in" (Ops.filterAllIn value 4)
383 , benchIOSink value "take-all" (Ops.takeAll value 4)
384 , benchIOSink value "takeWhile-true" (Ops.takeWhileTrue value 4)
385 --, benchIOSink value "takeWhileM-true" (Ops.takeWhileMTrue 4)
386 , benchIOSink value "drop-one" (Ops.dropOne 4)
387 , benchIOSink value "drop-all" (Ops.dropAll value 4)
388 , benchIOSink value "dropWhile-true" (Ops.dropWhileTrue value 4)
389 --, benchIOSink value "dropWhileM-true" (Ops.dropWhileMTrue 4)
390 , benchIOSink value "dropWhile-false" (Ops.dropWhileFalse value 4)
391 , benchIOSink value "deleteBy" (Ops.deleteBy value 4)
392 , benchIOSink value "intersperse" (Ops.intersperse value 4)
393 , benchIOSink value "insertBy" (Ops.insertBy value 4)
394 ]
395 , bgroup "joining"
396 [ benchIOSrc1 "zip (2,x/2)" (Ops.zip (value `div` 2))
397 , benchIOSrc1 "zipM (2,x/2)" (Ops.zipM (value `div` 2))
398 , benchIOSrc1 "mergeBy (2,x/2)" (Ops.mergeBy (value `div` 2))
399 , benchIOSrc1 "serial (2,x/2)" (Ops.serial2 (value `div` 2))
400 , benchIOSrc1 "append (2,x/2)" (Ops.append2 (value `div` 2))
401 , benchIOSrc1 "serial (2,2,x/4)" (Ops.serial4 (value `div` 4))
402 , benchIOSrc1 "append (2,2,x/4)" (Ops.append4 (value `div` 4))
403 , benchIOSrc1 "wSerial (2,x/2)" (Ops.wSerial2 value)
404 , benchIOSrc1 "interleave (2,x/2)" (Ops.interleave2 value)
405 , benchIOSrc1 "roundRobin (2,x/2)" (Ops.roundRobin2 value)
406 ]
407 , bgroup "concat-foldable"
408 [ benchIOSrc serially "foldMapWith" (Ops.sourceFoldMapWith value)
409 , benchIOSrc serially "foldMapWithM" (Ops.sourceFoldMapWithM value)
410 , benchIOSrc serially "foldMapM" (Ops.sourceFoldMapM value)
411 , benchIOSrc serially "foldWithConcatMapId" (Ops.sourceConcatMapId value)
412 ]
413 , bgroup "concat-serial"
414 [ benchIOSrc1 "concatMapPure (2,x/2)" (Ops.concatMapPure 2 (value `div` 2))
415 , benchIOSrc1 "concatMap (2,x/2)" (Ops.concatMap 2 (value `div` 2))
416 , benchIOSrc1 "concatMap (x/2,2)" (Ops.concatMap (value `div` 2) 2)
417 , benchIOSrc1 "concatMapRepl (x/4,4)" (Ops.concatMapRepl4xN value)
418 , benchIOSrc1 "concatUnfoldRepl (x/4,4)" (Ops.concatUnfoldRepl4xN value)
420 , benchIOSrc1 "concatMapWithSerial (2,x/2)"
421 (Ops.concatMapWithSerial 2 (value `div` 2))
422 , benchIOSrc1 "concatMapWithSerial (x/2,2)"
423 (Ops.concatMapWithSerial (value `div` 2) 2)
425 , benchIOSrc1 "concatMapWithAppend (2,x/2)"
426 (Ops.concatMapWithAppend 2 (value `div` 2))
427 ]
428 , bgroup "concat-interleave"
429 [ benchIOSrc1 "concatMapWithWSerial (2,x/2)"
430 (Ops.concatMapWithWSerial 2 (value `div` 2))
431 , benchIOSrc1 "concatMapWithWSerial (x/2,2)"
432 (Ops.concatMapWithWSerial (value `div` 2) 2)
433 , benchIOSrc1 "concatUnfoldInterleaveRepl (x/4,4)"
434 (Ops.concatUnfoldInterleaveRepl4xN value)
435 , benchIOSrc1 "concatUnfoldRoundrobinRepl (x/4,4)"
436 (Ops.concatUnfoldRoundrobinRepl4xN value)
437 ]
438 -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
439 -- library. If scan/fold followed by a map is efficient enough we may not
440 -- need monolithic implementations of these.
441 , bgroup "mixed"
442 [ benchIOSink value "scanl-map" (Ops.scanMap 1)
443 , benchIOSink value "foldl-map" Ops.foldl'ReduceMap
444 , benchIOSink value "sum-product-fold" Ops.sumProductFold
445 , benchIOSink value "sum-product-scan" Ops.sumProductScan
446 ]
447 , bgroup "mixedX4"
448 [ benchIOSink value "scan-map" (Ops.scanMap 4)
449 , benchIOSink value "drop-map" (Ops.dropMap 4)
450 , benchIOSink value "drop-scan" (Ops.dropScan 4)
451 , benchIOSink value "take-drop" (Ops.takeDrop value 4)
452 , benchIOSink value "take-scan" (Ops.takeScan value 4)
453 , benchIOSink value "take-map" (Ops.takeMap value 4)
454 , benchIOSink value "filter-drop" (Ops.filterDrop value 4)
455 , benchIOSink value "filter-take" (Ops.filterTake value 4)
456 , benchIOSink value "filter-scan" (Ops.filterScan 4)
457 , benchIOSink value "filter-scanl1" (Ops.filterScanl1 4)
458 , benchIOSink value "filter-map" (Ops.filterMap value 4)
459 ]
460 , bgroup "iterated"
461 [ benchIOSrc serially "mapM" Ops.iterateMapM
462 , benchIOSrc serially "scan(1/100)" Ops.iterateScan
463 , benchIOSrc serially "scanl1(1/100)" Ops.iterateScanl1
464 , benchIOSrc serially "filterEven" Ops.iterateFilterEven
465 , benchIOSrc serially "takeAll" (Ops.iterateTakeAll value)
466 , benchIOSrc serially "dropOne" Ops.iterateDropOne
467 , benchIOSrc serially "dropWhileFalse" (Ops.iterateDropWhileFalse value)
468 , benchIOSrc serially "dropWhileTrue" (Ops.iterateDropWhileTrue value)
469 ]
470 ]
471 , bgroup "wSerially"
472 [ bgroup "transformation"
473 [ benchIOSink value "fmap" $ Ops.fmap' wSerially 1
474 ]
475 ]
476 , bgroup "zipSerially"
477 [ bgroup "transformation"
478 [ benchIOSink value "fmap" $ Ops.fmap' zipSerially 1
479 ]
480 ]
481 , bgroup "zipAsyncly"
482 [ bgroup "transformation"
483 [ benchIOSink value "fmap" $ Ops.fmap' zipAsyncly 1
484 ]
485 ]
486 ]