4-- Copyright : (c) 2018 Harendra Kumar
7-- Maintainer : harendra.kumar@gmail.com
9import Control.DeepSeq (NFData(..), deepseq)
10import Data.Functor.Identity (Identity, runIdentity)
11import System.Random (randomRIO)
12import Data.Monoid (Last(..))
14import qualified GHC.Exts as GHC
15import qualified LinearOps as Ops
18import qualified Streamly.Fold as FL
19import qualified Streamly.Mem.Array as A
20import qualified Streamly.Prelude as S
21-- import qualified Streamly.Sink as Sink
24-------------------------------------------------------------------------------
26-------------------------------------------------------------------------------
28-- We need a monadic bind here to make sure that the function f does not get
29-- completely optimized out by the compiler in some cases.
31-- | Takes a fold method, and uses it with a default source.
32{-# INLINE benchIOSink #-}
34 :: (IsStream t, NFData b)
35 => String -> (t IO Int -> IO b) -> Benchmark
36benchIOSink name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source
38-- XXX We should be using sourceUnfoldrM for fair comparison with IO monad, but
39-- we can't use it as it requires MonadAsync constraint.
40{-# INLINE benchIdentitySink #-}
42 :: (IsStream t, NFData b)
43 => String -> (t Identity Int -> Identity b) -> Benchmark
44benchIdentitySink name f = bench name $ nf (f . Ops.sourceUnfoldr) 1
46-- | Takes a source, and uses it with a default drain/fold method.
47{-# INLINE benchIOSrc #-}
49 :: (t IO a -> SerialT IO a)
54 bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
56{-# INLINE benchPure #-}
57benchPure :: NFData b => String -> (Int -> a) -> (a -> b) -> Benchmark
58benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
60{-# INLINE benchPureSink #-}
61benchPureSink :: NFData b => String -> (SerialT Identity Int -> b) -> Benchmark
62benchPureSink name f = benchPure name Ops.sourceUnfoldr f
64{-# INLINE benchPureSinkIO #-}
67 => String -> (SerialT Identity Int -> IO b) -> Benchmark
68benchPureSinkIO name f =
69 bench name $ nfIO $ randomRIO (1, 1) >>= f . Ops.sourceUnfoldr
71{-# INLINE benchPureSrc #-}
72benchPureSrc :: String -> (Int -> SerialT Identity a) -> Benchmark
73benchPureSrc name src = benchPure name src (runIdentity . S.drain)
76mkString = "fromList [1" ++ concat (replicate Ops.value ",1") ++ "]"
79mkListString = "[1" ++ concat (replicate Ops.value ",1") ++ "]"
82mkList = [1..Ops.value]
89 [ benchPureSink "id" id
90 , benchPureSink "eqBy" Ops.eqBy
91 , benchPureSink "==" Ops.eqInstance
92 , benchPureSink "/=" Ops.eqInstanceNotEq
93 , benchPureSink "cmpBy" Ops.cmpBy
94 , benchPureSink "<" Ops.ordInstance
95 , benchPureSink "min" Ops.ordInstanceMin
96 , benchPureSrc "IsList.fromList" Ops.sourceIsList
97 , benchPureSink "IsList.toList" GHC.toList
98 , benchPureSrc "IsString.fromString" Ops.sourceIsString
99 , mkString `deepseq` (bench "readsPrec pure streams" $
100 nf Ops.readInstance mkString)
101 , mkString `deepseq` (bench "readsPrec Haskell lists" $
102 nf Ops.readInstanceList mkListString)
103 , benchPureSink "showsPrec pure streams" Ops.showInstance
104 , mkList `deepseq` (bench "showPrec Haskell lists" $
105 nf Ops.showInstanceList mkList)
106 , benchPureSink "foldl'" Ops.pureFoldl'
107 , benchPureSink "foldable/foldl'" Ops.foldableFoldl'
108 , benchPureSink "foldable/sum" Ops.foldableSum
109 , benchPureSinkIO "traversable/mapM" Ops.traversableMapM
111 , bgroup "generation"
112 [ -- Most basic, barely stream continuations running
113 benchIOSrc serially "unfoldr" Ops.sourceUnfoldr
114 , benchIOSrc serially "unfoldrM" Ops.sourceUnfoldrM
115 , benchIOSrc serially "intFromTo" Ops.sourceIntFromTo
116 , benchIOSrc serially "intFromThenTo" Ops.sourceIntFromThenTo
117 , benchIOSrc serially "integerFromStep" Ops.sourceIntegerFromStep
118 , benchIOSrc serially "fracFromThenTo" Ops.sourceFracFromThenTo
119 , benchIOSrc serially "fracFromTo" Ops.sourceFracFromTo
120 , benchIOSrc serially "fromList" Ops.sourceFromList
121 , benchIOSrc serially "fromListM" Ops.sourceFromListM
122 -- These are essentially cons and consM
123 , benchIOSrc serially "fromFoldable" Ops.sourceFromFoldable
124 , benchIOSrc serially "fromFoldableM" Ops.sourceFromFoldableM
125 -- These are essentially appends
126 , benchIOSrc serially "foldMapWith" Ops.sourceFoldMapWith
127 , benchIOSrc serially "foldMapWithM" Ops.sourceFoldMapWithM
128 , benchIOSrc serially "foldMapM" Ops.sourceFoldMapM
130 , bgroup "elimination"
133 [ benchIOSink "foldrM" Ops.foldrMReduce
134 , benchIOSink "foldl'" Ops.foldl'Reduce
135 , benchIOSink "foldl1'" Ops.foldl1'Reduce
136 , benchIOSink "foldlM'" Ops.foldlM'Reduce
139 [ benchIdentitySink "foldrM" Ops.foldrMReduce
140 , benchIdentitySink "foldl'" Ops.foldl'Reduce
141 , benchIdentitySink "foldl1'" Ops.foldl1'Reduce
142 , benchIdentitySink "foldlM'" Ops.foldlM'Reduce
148 [ benchIOSink "foldrM" Ops.foldrMBuild
149 , benchIOSink "foldl'" Ops.foldl'Build
150 , benchIOSink "foldlM'" Ops.foldlM'Build
153 [ benchIdentitySink "foldrM" Ops.foldrMBuild
154 , benchIdentitySink "foldl'" Ops.foldl'Build
155 , benchIdentitySink "foldlM'" Ops.foldlM'Build
158 , benchIOSink "uncons" Ops.uncons
159 , benchIOSink "toNull" $ Ops.toNull serially
160 , benchIOSink "mapM_" Ops.mapM_
162 , benchIOSink "init" Ops.init
163 , benchIOSink "tail" Ops.tail
164 , benchIOSink "nullHeadTail" Ops.nullHeadTail
166 -- this is too low and causes all benchmarks reported in ns
167 -- , benchIOSink "head" Ops.head
168 , benchIOSink "last" Ops.last
169 -- , benchIOSink "lookup" Ops.lookup
170 , benchIOSink "find" Ops.find
171 , benchIOSink "findIndex" Ops.findIndex
172 , benchIOSink "elemIndex" Ops.elemIndex
174 -- this is too low and causes all benchmarks reported in ns
175 -- , benchIOSink "null" Ops.null
176 , benchIOSink "elem" Ops.elem
177 , benchIOSink "notElem" Ops.notElem
178 , benchIOSink "all" Ops.all
179 , benchIOSink "any" Ops.any
180 , benchIOSink "and" Ops.and
181 , benchIOSink "or" Ops.or
183 , benchIOSink "length" Ops.length
184 , benchIOSink "sum" Ops.sum
185 , benchIOSink "product" Ops.product
187 , benchIOSink "maximumBy" Ops.maximumBy
188 , benchIOSink "maximum" Ops.maximum
189 , benchIOSink "minimumBy" Ops.minimumBy
190 , benchIOSink "minimum" Ops.minimum
192 , benchIOSink "toList" Ops.toList
193 -- , benchIOSink "toListRev" Ops.toListRev
196 [ benchIOSink "drain" (FL.foldl' FL.drain)
197 -- , benchIOSink "sink" (Sink.sink Sink.drain)
198 , benchIOSink "last" (FL.foldl' FL.last)
199 , benchIOSink "length" (FL.foldl' FL.length)
200 , benchIOSink "sum" (FL.foldl' FL.sum)
201 , benchIOSink "product" (FL.foldl' FL.product)
202 , benchIOSink "maximumBy" (FL.foldl' (FL.maximumBy compare))
203 , benchIOSink "maximum" (FL.foldl' FL.maximum)
204 , benchIOSink "minimumBy" (FL.foldl' (FL.minimumBy compare))
205 , benchIOSink "minimum" (FL.foldl' FL.minimum)
206 , benchIOSink "mean" (\s -> FL.foldl' FL.mean (S.map (fromIntegral :: Int -> Double) s))
207 , benchIOSink "variance" (\s -> FL.foldl' FL.variance (S.map (fromIntegral :: Int -> Double) s))
208 , benchIOSink "stdDev" (\s -> FL.foldl' FL.stdDev (S.map (fromIntegral :: Int -> Double) s))
210 , benchIOSink "mconcat" (FL.foldl' FL.mconcat . (S.map (Last . Just)))
211 , benchIOSink "foldMap" (FL.foldl' (FL.foldMap (Last . Just)))
213 -- , benchIOSink "toList" (FL.foldl' FL.toList)
214 , benchIOSink "toListRev" (FL.foldl' FL.toListRev)
215 -- , benchIOSink "toStream" (FL.foldl' FL.toStream)
216 , benchIOSink "toStreamRev" (FL.foldl' FL.toStreamRev)
217 , benchIOSink "toArrayN" (FL.foldl' (A.toArrayN Ops.value))
219 , benchIOSink "index" (FL.foldl' (FL.index Ops.maxValue))
220 , benchIOSink "head" (FL.foldl' FL.head)
221 , benchIOSink "find" (FL.foldl' (FL.find (== Ops.maxValue)))
222 , benchIOSink "findIndex" (FL.foldl' (FL.findIndex (== Ops.maxValue)))
223 , benchIOSink "elemIndex" (FL.foldl' (FL.elemIndex Ops.maxValue))
225 , benchIOSink "null" (FL.foldl' FL.null)
226 , benchIOSink "elem" (FL.foldl' (FL.elem Ops.maxValue))
227 , benchIOSink "notElem" (FL.foldl' (FL.notElem Ops.maxValue))
228 , benchIOSink "all" (FL.foldl' (FL.all (<= Ops.maxValue)))
229 , benchIOSink "any" (FL.foldl' (FL.any (> Ops.maxValue)))
230 , benchIOSink "and" (\s -> FL.foldl' FL.and (S.map (<= Ops.maxValue) s))
231 , benchIOSink "or" (\s -> FL.foldl' FL.or (S.map (> Ops.maxValue) s))
233 , bgroup "folds-mixed" -- Applicative
235 benchIOSink "all,any" (FL.foldl' ((,) <$> FL.all (<= Ops.maxValue)
236 <*> FL.any (> Ops.maxValue)))
237 , benchIOSink "sum,length" (FL.foldl' ((,) <$> FL.sum <*> FL.length))
239 , bgroup "transformation"
240 [ benchIOSink "scanl" (Ops.scan 1)
241 , benchIOSink "scanl1'" (Ops.scanl1' 1)
242 , benchIOSink "map" (Ops.map 1)
243 , benchIOSink "fmap" (Ops.fmap 1)
244 , benchIOSink "mapM" (Ops.mapM serially 1)
245 , benchIOSink "mapMaybe" (Ops.mapMaybe 1)
246 , benchIOSink "mapMaybeM" (Ops.mapMaybeM 1)
247 , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
248 Ops.sequence serially (Ops.sourceUnfoldrMAction n)
249 , benchIOSink "findIndices" (Ops.findIndices 1)
250 , benchIOSink "elemIndices" (Ops.elemIndices 1)
251 , benchIOSink "reverse" (Ops.reverse 1)
252 , benchIOSink "reverse'" (Ops.reverse' 1)
253 , benchIOSink "foldrS" (Ops.foldrS 1)
254 , benchIOSink "foldrSMap" (Ops.foldrSMap 1)
255 , benchIOSink "foldrT" (Ops.foldrT 1)
256 , benchIOSink "foldrTMap" (Ops.foldrTMap 1)
258 , bgroup "transformationX4"
259 [ benchIOSink "scan" (Ops.scan 4)
260 , benchIOSink "scanl1'" (Ops.scanl1' 4)
261 , benchIOSink "map" (Ops.map 4)
262 , benchIOSink "fmap" (Ops.fmap 4)
263 , benchIOSink "mapM" (Ops.mapM serially 4)
264 , benchIOSink "mapMaybe" (Ops.mapMaybe 4)
265 , benchIOSink "mapMaybeM" (Ops.mapMaybeM 4)
266 -- , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
267 -- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
268 , benchIOSink "findIndices" (Ops.findIndices 4)
269 , benchIOSink "elemIndices" (Ops.elemIndices 4)
272 [ benchIOSink "filter-even" (Ops.filterEven 1)
273 , benchIOSink "filter-all-out" (Ops.filterAllOut 1)
274 , benchIOSink "filter-all-in" (Ops.filterAllIn 1)
275 , benchIOSink "take-all" (Ops.takeAll 1)
276 , benchIOSink "takeWhile-true" (Ops.takeWhileTrue 1)
277 --, benchIOSink "takeWhileM-true" (Ops.takeWhileMTrue 1)
278 , benchIOSink "drop-one" (Ops.dropOne 1)
279 , benchIOSink "drop-all" (Ops.dropAll 1)
280 , benchIOSink "dropWhile-true" (Ops.dropWhileTrue 1)
281 --, benchIOSink "dropWhileM-true" (Ops.dropWhileMTrue 1)
282 , benchIOSink "dropWhile-false" (Ops.dropWhileFalse 1)
283 , benchIOSink "deleteBy" (Ops.deleteBy 1)
284 , benchIOSink "insertBy" (Ops.insertBy 1)
286 , bgroup "filteringX4"
287 [ benchIOSink "filter-even" (Ops.filterEven 4)
288 , benchIOSink "filter-all-out" (Ops.filterAllOut 4)
289 , benchIOSink "filter-all-in" (Ops.filterAllIn 4)
290 , benchIOSink "take-all" (Ops.takeAll 4)
291 , benchIOSink "takeWhile-true" (Ops.takeWhileTrue 4)
292 --, benchIOSink "takeWhileM-true" (Ops.takeWhileMTrue 4)
293 , benchIOSink "drop-one" (Ops.dropOne 4)
294 , benchIOSink "drop-all" (Ops.dropAll 4)
295 , benchIOSink "dropWhile-true" (Ops.dropWhileTrue 4)
296 --, benchIOSink "dropWhileM-true" (Ops.dropWhileMTrue 4)
297 , benchIOSink "dropWhile-false" (Ops.dropWhileFalse 4)
298 , benchIOSink "deleteBy" (Ops.deleteBy 4)
299 , benchIOSink "insertBy" (Ops.insertBy 4)
301 , bgroup "multi-stream"
302 [ benchIOSink "eqBy" Ops.eqBy
303 , benchIOSink "cmpBy" Ops.cmpBy
304 , benchIOSink "zip" Ops.zip
305 , benchIOSink "zipM" Ops.zipM
306 , benchIOSink "mergeBy" Ops.mergeBy
307 , benchIOSink "isPrefixOf" Ops.isPrefixOf
308 , benchIOSink "isSubsequenceOf" Ops.isSubsequenceOf
309 , benchIOSink "stripPrefix" Ops.stripPrefix
310 , benchIOSrc serially "concatMap" Ops.concatMap
312 -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
313 -- library. If scan/fold followed by a map is efficient enough we may not
314 -- need monolithic implementations of these.
316 [ benchIOSink "scanl-map" (Ops.scanMap 1)
317 , benchIOSink "foldl-map" Ops.foldl'ReduceMap
318 , benchIOSink "sum-product-fold" Ops.sumProductFold
319 , benchIOSink "sum-product-scan" Ops.sumProductScan
322 [ benchIOSink "scan-map" (Ops.scanMap 4)
323 , benchIOSink "drop-map" (Ops.dropMap 4)
324 , benchIOSink "drop-scan" (Ops.dropScan 4)
325 , benchIOSink "take-drop" (Ops.takeDrop 4)
326 , benchIOSink "take-scan" (Ops.takeScan 4)
327 , benchIOSink "take-map" (Ops.takeMap 4)
328 , benchIOSink "filter-drop" (Ops.filterDrop 4)
329 , benchIOSink "filter-take" (Ops.filterTake 4)
330 , benchIOSink "filter-scan" (Ops.filterScan 4)
331 , benchIOSink "filter-scanl1" (Ops.filterScanl1 4)
332 , benchIOSink "filter-map" (Ops.filterMap 4)
335 [ benchIOSrc serially "mapM" Ops.iterateMapM
336 , benchIOSrc serially "scan(1/100)" Ops.iterateScan
337 , benchIOSrc serially "scanl1(1/100)" Ops.iterateScanl1
338 , benchIOSrc serially "filterEven" Ops.iterateFilterEven
339 , benchIOSrc serially "takeAll" Ops.iterateTakeAll
340 , benchIOSrc serially "dropOne" Ops.iterateDropOne
341 , benchIOSrc serially "dropWhileFalse" Ops.iterateDropWhileFalse
342 , benchIOSrc serially "dropWhileTrue" Ops.iterateDropWhileTrue
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list