on master help sign in
Add more concatMap benchmarks

* concat pure streams * concat n x n * use replicate with concatMap

commit8552589390b314d3e63a1a4606d3f7dccb14b379 authorHarendra Kumar <harendra.kumar@gmail.com> dateFri 26 Jul 2019, 19:04 (7 years ago) parenta74914d
5 files changed+54−15
benchmark/BaseStreams.hs+8−4 benchmark/Linear.hs+4−1 benchmark/LinearOps.hs+32−10 benchmark/StreamDOps.hs+4 benchmark/StreamKOps.hs+6
benchmark/BaseStreams.hs+8−4
@@ -99,8 +99,10 @@ main =
9999 , benchIO "mapM" (D.mapM 1) D.sourceUnfoldrM
100100 , benchIO "mapMaybe" (D.mapMaybe 1) D.sourceUnfoldrM
101101 , benchIO "mapMaybeM" (D.mapMaybeM 1) D.sourceUnfoldrM
102− , benchIO "concatMap" (D.concatMap 1) (D.sourceUnfoldrMN D.value2)
103− , benchIO "concatMapPure" (D.concatMap 1) (D.sourceUnfoldrN D.value2)
102+ , benchIO "concatMapNxN" (D.concatMap 1) (D.sourceUnfoldrMN D.value2)
103+ , benchIO "concatMapRepl4xN" D.concatMapRepl4xN
104+ (D.sourceUnfoldrMN (D.value `div` 4))
105+ , benchIO "concatMapPureNxN" (D.concatMap 1) (D.sourceUnfoldrN D.value2)
104106 , benchIO "intersperse" (D.intersperse 1) (D.sourceUnfoldrMN D.value2)
105107 , benchIO "interspersePure" (D.intersperse 1) (D.sourceUnfoldrN D.value2)
106108 -- , benchIO "foldrS" (D.foldrS 1) D.sourceUnfoldrM
@@ -243,8 +245,10 @@ main =
243245 , benchIO "mapM" (K.mapM 1) K.sourceUnfoldrM
244246 , benchIO "mapMSerial" (K.mapMSerial 1) K.sourceUnfoldrM
245247 -- , benchIOSrcK "concatMap" K.concatMap
246− , benchIO "concatMap" (K.concatMap 1) (K.sourceUnfoldrMN K.value2)
247− , benchIO "concatMapPure" (K.concatMap 1) (K.sourceUnfoldrN K.value2)
248+ , benchIO "concatMapNxN" (K.concatMap 1) (K.sourceUnfoldrMN K.value2)
249+ , benchIO "concatMapPureNxN" (K.concatMap 1) (K.sourceUnfoldrN K.value2)
250+ , benchIO "concatMapRepl4xN" K.concatMapRepl4xN
251+ (K.sourceUnfoldrMN (K.value `div` 4))
248252 , benchIO "intersperse" (K.intersperse 1) (K.sourceUnfoldrMN K.value2)
249253 , benchIO "interspersePure" (K.intersperse 1) (K.sourceUnfoldrN K.value2)
250254 , benchIO "foldlS" (K.foldlS 1) K.sourceUnfoldrM
benchmark/Linear.hs+4−1
@@ -336,7 +336,10 @@ main =
336336 , benchIOSink "isPrefixOf" Ops.isPrefixOf
337337 , benchIOSink "isSubsequenceOf" Ops.isSubsequenceOf
338338 , benchIOSink "stripPrefix" Ops.stripPrefix
339− , benchIOSrc serially "concatMap" Ops.concatMap
339+ , benchIOSrc serially "concatMap1xN" Ops.concatMap
340+ , benchIOSrc serially "concatMapPure1xN" Ops.concatMapPure1xN
341+ , benchIOSrc serially "concatMapNxN" Ops.concatMapNxN
342+ , benchIOSrc serially "concatMapRepl4xN" Ops.concatMapRepl4xN
340343 ]
341344 -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
342345 -- library. If scan/fold followed by a map is efficient enough we may not
benchmark/LinearOps.hs+32−10
@@ -126,6 +126,15 @@ sourceUnfoldr n = S.unfoldr step n
126126 then Nothing
127127 else Just (cnt, cnt + 1)
128128
129+{-# INLINE sourceUnfoldrN #-}
130+sourceUnfoldrN :: (Monad m, S.IsStream t) => Int -> Int -> t m Int
131+sourceUnfoldrN upto start = S.unfoldr step start
132+ where
133+ step cnt =
134+ if cnt > start + upto
135+ then Nothing
136+ else Just (cnt, cnt + 1)
137+
129138{-# INLINE sourceUnfoldrM #-}
130139sourceUnfoldrM :: (S.IsStream t, S.MonadAsync m) => Int -> t m Int
131140sourceUnfoldrM n = S.unfoldrM step n
@@ -137,10 +146,10 @@ sourceUnfoldrM n = S.unfoldrM step n
137146
138147{-# INLINE sourceUnfoldrMN #-}
139148sourceUnfoldrMN :: (S.IsStream t, S.MonadAsync m) => Int -> Int -> t m Int
140−sourceUnfoldrMN m n = S.unfoldrM step n
149+sourceUnfoldrMN upto start = S.unfoldrM step start
141150 where
142151 step cnt =
143− if cnt > n + m
152+ if cnt > start + upto
144153 then return Nothing
145154 else return (Just (cnt, cnt + 1))
146155
@@ -533,16 +542,29 @@ eqBy src = S.eqBy (==) src src
533542cmpBy :: (Monad m, P.Ord a) => Stream m a -> m P.Ordering
534543cmpBy src = S.cmpBy P.compare src src
535544
536−concatStreamLen, maxNested :: Int
537−-- concatStreamLen = value2
538−-- maxNested = value2
539−concatStreamLen = 1
540−maxNested = 100000
541−
545+-- The worst case for concatMap, concat a 1 element stream n times.
542546{-# INLINE concatMap #-}
543547concatMap :: S.MonadAsync m => Int -> Stream m Int
544−concatMap n = S.concatMap (\_ -> sourceUnfoldrMN maxNested n)
545− (sourceUnfoldrMN concatStreamLen n)
548+concatMap n = S.concatMap (\_ -> sourceUnfoldrMN 1 n)
549+ (sourceUnfoldrMN value n)
550+
551+{-# INLINE concatMapPure1xN #-}
552+concatMapPure1xN :: S.MonadAsync m => Int -> Stream m Int
553+concatMapPure1xN n = S.concatMap (\_ -> sourceUnfoldrN 1 n)
554+ (sourceUnfoldrN value n)
555+
556+-- We use a (sqrt n) element stream as source and then generate and concat a
557+-- (sqrt n) element stream for each element of the source to produce an n
558+-- element stream.
559+{-# INLINE concatMapNxN #-}
560+concatMapNxN :: S.MonadAsync m => Int -> Stream m Int
561+concatMapNxN n = S.concatMap (\_ -> sourceUnfoldrMN value2 n)
562+ (sourceUnfoldrMN value2 n)
563+
564+{-# INLINE concatMapRepl4xN #-}
565+concatMapRepl4xN :: S.MonadAsync m => Int -> Stream m Int
566+concatMapRepl4xN n = S.concatMap (S.replicate 4)
567+ (sourceUnfoldrMN (value `div` 4) n)
546568
547569-------------------------------------------------------------------------------
548570-- Mixed Composition
benchmark/StreamDOps.hs+4
@@ -266,6 +266,10 @@ cmpBy src = S.cmpBy P.compare src src
266266zip :: Monad m => Stream m Int -> m ()
267267zip src = transform $ S.zipWith (,) src src
268268
269+{-# INLINE concatMapRepl4xN #-}
270+concatMapRepl4xN :: Monad m => Stream m Int -> m ()
271+concatMapRepl4xN src = transform $ (S.concatMap (S.replicate 4) src)
272+
269273-------------------------------------------------------------------------------
270274-- Mixed Composition
271275-------------------------------------------------------------------------------
benchmark/StreamKOps.hs+6
@@ -225,6 +225,8 @@ dropAll n = composeN n $ S.drop maxValue
225225dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
226226dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
227227foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
228+-- We use a (sqrt n) element stream as source and then concat the same stream
229+-- for each element to produce an n element stream.
228230concatMap n = composeN n $ (\s -> S.concatMap (\_ -> s) s)
229231intersperse n = composeN n $ S.intersperse maxValue
230232
@@ -274,6 +276,10 @@ iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
274276
275277zip src = transform $ S.zipWith (,) src src
276278
279+{-# INLINE concatMapRepl4xN #-}
280+concatMapRepl4xN :: Monad m => Stream m Int -> m ()
281+concatMapRepl4xN src = transform $ (S.concatMap (S.replicate 4) src)
282+
277283-------------------------------------------------------------------------------
278284-- Mixed Composition
279285-------------------------------------------------------------------------------