on master help sign in
Add inspection tests for some benchmarks (eq/cmp/merge/zip)
commit0ef35be05bc381c127eca90721f1bb92a921698c authorHarendra Kumar <harendra.kumar@gmail.com> dateFri 23 Aug 2019, 17:43 (7 years ago) parent11b10b9
2 files changed+83−18
benchmark/Linear.hs+19−6 src/Streamly/Benchmark/Prelude.hs+64−12
benchmark/Linear.hs+19−6
@@ -45,6 +45,12 @@ benchIOSink
4545 => String -> (t IO Int -> IO b) -> Benchmark
4646benchIOSink name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source
4747
48+-- XXX once we convert all the functions to use this we can rename this to
49+-- benchIOSink
50+{-# INLINE benchIOSink1 #-}
51+benchIOSink1 :: NFData b => String -> (Int -> IO b) -> Benchmark
52+benchIOSink1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
53+
4854-- XXX We should be using sourceUnfoldrM for fair comparison with IO monad, but
4955-- we can't use it as it requires MonadAsync constraint.
5056{-# INLINE benchIdentitySink #-}
@@ -71,6 +77,13 @@ benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
7177benchPureSink :: NFData b => String -> (SerialT Identity Int -> b) -> Benchmark
7278benchPureSink name f = benchPure name Ops.sourceUnfoldr f
7379
80+-- XXX once we convert all the functions to use this we can rename this to
81+-- benchPureSink
82+{-# INLINE benchPureSink1 #-}
83+benchPureSink1 :: NFData b => String -> (Int -> Identity b) -> Benchmark
84+benchPureSink1 name f =
85+ bench name $ nfIO $ randomRIO (1,1) >>= return . runIdentity . f
86+
7487{-# INLINE benchPureSinkIO #-}
7588benchPureSinkIO
7689 :: NFData b
@@ -97,10 +110,10 @@ main =
97110 [ bgroup "serially"
98111 [ bgroup "pure"
99112 [ benchPureSink "id" id
100− , benchPureSink "eqBy" Ops.eqBy
113+ , benchPureSink1 "eqBy" Ops.eqByPure
101114 , benchPureSink "==" Ops.eqInstance
102115 , benchPureSink "/=" Ops.eqInstanceNotEq
103− , benchPureSink "cmpBy" Ops.cmpBy
116+ , benchPureSink1 "cmpBy" Ops.cmpByPure
104117 , benchPureSink "<" Ops.ordInstance
105118 , benchPureSink "min" Ops.ordInstanceMin
106119 , benchPureSrc "IsList.fromList" Ops.sourceIsList
@@ -329,11 +342,11 @@ main =
329342 , benchIOSink "insertBy" (Ops.insertBy 4)
330343 ]
331344 , bgroup "multi-stream"
332− [ benchIOSink "eqBy" Ops.eqBy
333− , benchIOSink "cmpBy" Ops.cmpBy
345+ [ benchIOSink1 "eqBy" Ops.eqBy
346+ , benchIOSink1 "cmpBy" Ops.cmpBy
334347 , benchIOSink "zip" Ops.zip
335− , benchIOSink "zipM" Ops.zipM
336− , benchIOSink "mergeBy" Ops.mergeBy
348+ , benchIOSink1 "zipM" Ops.zipM
349+ , benchIOSink1 "mergeBy" Ops.mergeBy
337350 , benchIOSink "isPrefixOf" Ops.isPrefixOf
338351 , benchIOSink "isSubsequenceOf" Ops.isSubsequenceOf
339352 , benchIOSink "stripPrefix" Ops.stripPrefix
src/Streamly/Benchmark/Prelude.hs+64−12
@@ -10,13 +10,18 @@
1010{-# LANGUAGE ScopedTypeVariables #-}
1111{-# LANGUAGE DeriveAnyClass #-}
1212{-# LANGUAGE DeriveGeneric #-}
13+{-# LANGUAGE TemplateHaskell #-}
14+
15+{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
1316
1417module Streamly.Benchmark.Prelude where
1518
19+import Control.DeepSeq (NFData)
1620import Control.Monad (when)
1721import Control.Monad.IO.Class (MonadIO)
1822import Data.Functor.Identity (Identity, runIdentity)
1923import Data.Maybe (fromJust)
24+import GHC.Generics (Generic)
2025import Prelude
2126 (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=), (==), (>=),
2227 subtract, undefined, Maybe(..), odd, Bool, not, (>>=), mapM_, curry,
@@ -25,8 +30,11 @@ import Prelude
2530import qualified Prelude as P
2631import qualified Data.Foldable as F
2732import qualified GHC.Exts as GHC
28−import Control.DeepSeq (NFData)
29−import GHC.Generics (Generic)
33+
34+import Test.Inspection
35+
36+import Streamly.Streams.StreamD.Type (Step(..))
37+import Streamly.Benchmark.Inspection (hinspect)
3038
3139import qualified Streamly as S hiding (foldMapWith, runStream)
3240import qualified Streamly.Prelude as S
@@ -489,24 +497,40 @@ iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
489497-------------------------------------------------------------------------------
490498
491499{-# INLINE zip #-}
492−{-# INLINE zipM #-}
493−{-# INLINE mergeBy #-}
494−zip, zipM, mergeBy :: Monad m => Stream m Int -> m ()
495−
500+zip :: Monad m => Stream m Int -> m ()
496501zip src = do
497502 r <- S.tail src
498503 let src1 = fromJust r
499504 transform (S.zipWith (,) src src1)
500−zipM src = do
505+
506+{-# INLINE zipM' #-}
507+zipM' :: Monad m => Stream m Int -> m ()
508+zipM' src = do
501509 r <- S.tail src
502510 let src1 = fromJust r
503511 transform (S.zipWithM (curry return) src src1)
504512
505−mergeBy src = do
513+{-# INLINE zipM #-}
514+zipM :: Int -> IO ()
515+zipM n = zipM' $ source n
516+
517+hinspect $ hasNoTypeClasses 'zipM
518+-- hinspect $ 'zipM `hasNoType` ''Step
519+
520+{-# INLINE mergeBy' #-}
521+mergeBy' :: Monad m => Stream m Int -> m ()
522+mergeBy' src = do
506523 r <- S.tail src
507524 let src1 = fromJust r
508525 transform (S.mergeBy P.compare src src1)
509526
527+{-# INLINE mergeBy #-}
528+mergeBy :: Int -> IO ()
529+mergeBy n = mergeBy' $ source n
530+
531+hinspect $ hasNoTypeClasses 'mergeBy
532+-- hinspect $ 'mergeBy `hasNoType` ''Step
533+
510534{-# INLINE isPrefixOf #-}
511535{-# INLINE isSubsequenceOf #-}
512536isPrefixOf, isSubsequenceOf :: Monad m => Stream m Int -> m Bool
@@ -541,13 +565,41 @@ zipAsyncAp src = do
541565 transform (S.zipAsyncly $ (,) <$> S.serially src
542566 <*> S.serially src1)
543567
568+{-# INLINE eqBy' #-}
569+eqBy' :: (Monad m, P.Eq a) => Stream m a -> m P.Bool
570+eqBy' src = S.eqBy (==) src src
571+
544572{-# INLINE eqBy #-}
545−eqBy :: (Monad m, P.Eq a) => Stream m a -> m P.Bool
546−eqBy src = S.eqBy (==) src src
573+eqBy :: Int -> IO Bool
574+eqBy n = eqBy' (source n)
575+
576+hinspect $ hasNoTypeClasses 'eqBy
577+hinspect $ 'eqBy `hasNoType` ''Step
578+
579+{-# INLINE eqByPure #-}
580+eqByPure :: Int -> Identity Bool
581+eqByPure n = eqBy' (sourceUnfoldr n)
582+
583+hinspect $ hasNoTypeClasses 'eqByPure
584+hinspect $ 'eqByPure `hasNoType` ''Step
585+
586+{-# INLINE cmpBy' #-}
587+cmpBy' :: (Monad m, P.Ord a) => Stream m a -> m P.Ordering
588+cmpBy' src = S.cmpBy P.compare src src
547589
548590{-# INLINE cmpBy #-}
549−cmpBy :: (Monad m, P.Ord a) => Stream m a -> m P.Ordering
550−cmpBy src = S.cmpBy P.compare src src
591+cmpBy :: Int -> IO P.Ordering
592+cmpBy n = cmpBy' (source n)
593+
594+hinspect $ hasNoTypeClasses 'cmpBy
595+hinspect $ 'cmpBy `hasNoType` ''Step
596+
597+{-# INLINE cmpByPure #-}
598+cmpByPure :: Int -> Identity P.Ordering
599+cmpByPure n = cmpBy' (sourceUnfoldr n)
600+
601+hinspect $ hasNoTypeClasses 'cmpByPure
602+hinspect $ 'cmpByPure `hasNoType` ''Step
551603
552604-- The worst case for concatMap, concat a 1 element stream n times.
553605{-# INLINE concatMap #-}