on master help sign in
move the concatMap inspection test to benchmarks
6f06bddHarendra Kumar
benchmark/Linear.hs+8−4
@@ -69,6 +69,10 @@ benchIOSrc
69benchIOSrc t name f =
69benchIOSrc t name f =
70 bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
70 bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
71
71
72+{-# INLINE benchIOSrc1 #-}
73+benchIOSrc1 :: String -> (Int -> IO ()) -> Benchmark
74+benchIOSrc1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
75+
72{-# INLINE benchPure #-}
76{-# INLINE benchPure #-}
73benchPure :: NFData b => String -> (Int -> a) -> (a -> b) -> Benchmark
77benchPure :: NFData b => String -> (Int -> a) -> (a -> b) -> Benchmark
74benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
78benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
@@ -350,10 +354,10 @@ main =
350 , benchIOSink "isPrefixOf" Ops.isPrefixOf
354 , benchIOSink "isPrefixOf" Ops.isPrefixOf
351 , benchIOSink "isSubsequenceOf" Ops.isSubsequenceOf
355 , benchIOSink "isSubsequenceOf" Ops.isSubsequenceOf
352 , benchIOSink "stripPrefix" Ops.stripPrefix
356 , benchIOSink "stripPrefix" Ops.stripPrefix
353− , benchIOSrc serially "concatMap1xN" Ops.concatMap
357+ , benchIOSrc1 "concatMap1xN" Ops.concatMap
354− , benchIOSrc serially "concatMapPure1xN" Ops.concatMapPure1xN
358+ , benchIOSrc1 "concatMapPure1xN" Ops.concatMapPure1xN
355− , benchIOSrc serially "concatMapNxN" Ops.concatMapNxN
359+ , benchIOSrc1 "concatMapNxN" Ops.concatMapNxN
356− , benchIOSrc serially "concatMapRepl4xN" Ops.concatMapRepl4xN
360+ , benchIOSrc1 "concatMapRepl4xN" Ops.concatMapRepl4xN
357 ]
361 ]
358 -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
362 -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
359 -- library. If scan/fold followed by a map is efficient enough we may not
363 -- library. If scan/fold followed by a map is efficient enough we may not
src/Streamly/Benchmark/Prelude.hs+24−10
@@ -595,7 +595,6 @@ inspect $ hasNoTypeClasses 'eqByPure
595inspect $ 'eqByPure `hasNoType` ''Step
595inspect $ 'eqByPure `hasNoType` ''Step
596#endif
596#endif
597
597
598−
599{-# INLINE cmpBy' #-}
598{-# INLINE cmpBy' #-}
600cmpBy' :: (Monad m, P.Ord a) => Stream m a -> m P.Ordering
599cmpBy' :: (Monad m, P.Ord a) => Stream m a -> m P.Ordering
601cmpBy' src = S.cmpBy P.compare src src
600cmpBy' src = S.cmpBy P.compare src src
@@ -609,7 +608,6 @@ inspect $ hasNoTypeClasses 'cmpBy
609inspect $ 'cmpBy `hasNoType` ''Step
608inspect $ 'cmpBy `hasNoType` ''Step
610#endif
609#endif
611
610
612−
613{-# INLINE cmpByPure #-}
611{-# INLINE cmpByPure #-}
614cmpByPure :: Int -> Identity P.Ordering
612cmpByPure :: Int -> Identity P.Ordering
615cmpByPure n = cmpBy' (sourceUnfoldr n)
613cmpByPure n = cmpBy' (sourceUnfoldr n)
@@ -621,28 +619,44 @@ inspect $ 'cmpByPure `hasNoType` ''Step
621
619
622-- The worst case for concatMap, concat a 1 element stream n times.
620-- The worst case for concatMap, concat a 1 element stream n times.
623{-# INLINE concatMap #-}
621{-# INLINE concatMap #-}
624−concatMap :: S.MonadAsync m => Int -> Stream m Int
622+concatMap :: Int -> IO ()
625−concatMap n = S.concatMap (\_ -> sourceUnfoldrMN 1 n)
623+concatMap n = S.drain $ S.concatMap (\_ -> sourceUnfoldrMN 1 n)
626 (sourceUnfoldrMN value n)
624 (sourceUnfoldrMN value n)
627
625
626+#ifdef INSPECTION
627+inspect $ hasNoTypeClasses 'concatMap
628+#endif
629+
628{-# INLINE concatMapPure1xN #-}
630{-# INLINE concatMapPure1xN #-}
629−concatMapPure1xN :: S.MonadAsync m => Int -> Stream m Int
631+concatMapPure1xN :: Int -> IO ()
630−concatMapPure1xN n = S.concatMap (\_ -> sourceUnfoldrN 1 n)
632+concatMapPure1xN n = S.drain $ S.concatMap (\_ -> sourceUnfoldrN 1 n)
631 (sourceUnfoldrN value n)
633 (sourceUnfoldrN value n)
632
634
635+#ifdef INSPECTION
636+inspect $ hasNoTypeClasses 'concatMapPure1xN
637+#endif
638+
633-- We use a (sqrt n) element stream as source and then generate and concat a
639-- We use a (sqrt n) element stream as source and then generate and concat a
634-- (sqrt n) element stream for each element of the source to produce an n
640-- (sqrt n) element stream for each element of the source to produce an n
635-- element stream.
641-- element stream.
636{-# INLINE concatMapNxN #-}
642{-# INLINE concatMapNxN #-}
637−concatMapNxN :: S.MonadAsync m => Int -> Stream m Int
643+concatMapNxN :: Int -> IO ()
638−concatMapNxN n = S.concatMap (\_ -> sourceUnfoldrMN value2 n)
644+concatMapNxN n = S.drain $ S.concatMap (\_ -> sourceUnfoldrMN value2 n)
639 (sourceUnfoldrMN value2 n)
645 (sourceUnfoldrMN value2 n)
640
646
647+#ifdef INSPECTION
648+inspect $ hasNoTypeClasses 'concatMapNxN
649+#endif
650+
641{-# INLINE concatMapRepl4xN #-}
651{-# INLINE concatMapRepl4xN #-}
642−concatMapRepl4xN :: S.MonadAsync m => Int -> Stream m Int
652+concatMapRepl4xN :: Int -> IO ()
643−concatMapRepl4xN n = S.concatMap (S.replicate 4)
653+concatMapRepl4xN n = S.drain $ S.concatMap (S.replicate 4)
644 (sourceUnfoldrMN (value `div` 4) n)
654 (sourceUnfoldrMN (value `div` 4) n)
645
655
656+#ifdef INSPECTION
657+inspect $ hasNoTypeClasses 'concatMapRepl4xN
658+#endif
659+
646-------------------------------------------------------------------------------
660-------------------------------------------------------------------------------
647-- Mixed Composition
661-- Mixed Composition
648-------------------------------------------------------------------------------
662-------------------------------------------------------------------------------
streamly.cabal−16
@@ -507,22 +507,6 @@ test-suite parallel-loops
507 , base >= 4.8 && < 5
507 , base >= 4.8 && < 5
508 , random >= 1.0.0 && < 2
508 , random >= 1.0.0 && < 2
509
509
510−test-suite inspection
511− import: test-options
512− type: exitcode-stdio-1.0
513− default-language: Haskell2010
514− main-is: inspection.hs
515− hs-source-dirs: test
516− build-Depends:
517− streamly
518− , base >= 4.8 && < 5
519− , inspection-testing >= 0.4 && < 0.5
520− if impl(ghc < 8.0)
521− buildable: False
522− -- On Windows we're getting "unknown symbol `clock_gettime'"
523− if os(windows)
524− buildable: False
525−
526-------------------------------------------------------------------------------
510-------------------------------------------------------------------------------
527-- Benchmarks
511-- Benchmarks
528-------------------------------------------------------------------------------
512-------------------------------------------------------------------------------
test/inspection.hsdeleted−33
@@ -1,33 +0,0 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE TemplateHaskell #-}
3−
4−{-# OPTIONS_GHC -O -fplugin Test.Inspection.Plugin #-}
5−
6−import Streamly
7−import qualified Streamly.Prelude as S
8−import Test.Inspection
9−
10−main :: IO ()
11−main = pure () -- If the test compiles, it passes
12−
13−-------------------------------------------------------------------------------
14−-- #214 regression test: 'concatMap (replicate n)' should be specialized
15−-------------------------------------------------------------------------------
16−
17−{-# INLINE concatMap1 #-}
18−concatMap1 :: MonadAsync m => SerialT m Int -> m ()
19−concatMap1 src = S.drain $ S.concatMap (S.replicate 3) src
20−
21−{-# INLINE sourceUnfoldrMN #-}
22−sourceUnfoldrMN :: MonadAsync m => Int -> Int -> SerialT m Int
23−sourceUnfoldrMN m n = S.unfoldrM step n
24− where
25− step cnt =
26− if cnt > n + m
27− then return Nothing
28− else return (Just (cnt, cnt + 1))
29−
30−test214 :: IO ()
31−test214 = concatMap1 (sourceUnfoldrMN 1000000 5)
32−
33−inspect $ hasNoTypeClasses 'test214