streamly-0.2.0: benchmark/NestedOps.hs
-- |
-- Module : BenchmarkOps
-- Copyright : (c) 2018 Harendra Kumar
--
-- License : MIT
-- Maintainer : harendra.kumar@gmail.com
{-# LANGUAGE ScopedTypeVariables #-}
module NestedOps where
import Control.Exception (try)
import GHC.Exception (ErrorCall)
import qualified Streamly as S
import qualified Streamly.Prelude as S
sumCount :: Int
sumCount = 1000000
prodCount :: Int
prodCount = 1000
-------------------------------------------------------------------------------
-- Stream generation and elimination
-------------------------------------------------------------------------------
type Stream m a = S.SerialT m a
{-# INLINE source #-}
source :: S.IsStream t => Int -> Int -> t m Int
source start n = S.fromFoldable [start..start+n]
{-# INLINE runStream #-}
runStream :: Monad m => Stream m a -> m ()
runStream = S.runStream
{-# INLINE runToList #-}
runToList :: Monad m => Stream m a -> m [a]
runToList = S.toList
-------------------------------------------------------------------------------
-- Benchmark ops
-------------------------------------------------------------------------------
{-# INLINE toNullLinear #-}
toNullLinear :: Monad m => Int -> m ()
toNullLinear start = runStream $ source start sumCount
{-# INLINE toListLinear #-}
toListLinear :: Monad m => Int -> m [Int]
toListLinear start = runToList $ source start sumCount
{-# INLINE append #-}
append
:: (Monoid (t m Int), Monad m, Monad (t m))
=> (t m Int -> S.SerialT m Int) -> Int -> m ()
append t start = runStream $ t $ foldMap return [start..start+sumCount]
{-# INLINE toNull0 #-}
toNull0
:: (S.IsStream t, Monad m, Monad (t m))
=> (t m (Int, Int) -> S.SerialT m (Int, Int)) -> Int -> m ()
toNull0 t start = runStream . t $ do
x <- source start prodCount
y <- source start prodCount
return (x,y)
{-# INLINE toList0 #-}
toList0
:: (S.IsStream t, Monad m, Monad (t m))
=> (t m (Int, Int) -> S.SerialT m (Int, Int)) -> Int -> m [(Int, Int)]
toList0 t start = runToList . t $ do
x <- source start prodCount
y <- source start prodCount
return (x,y)
{-# INLINE toNull #-}
toNull
:: (S.IsStream t, Monad m, Monad (t m))
=> (t m Int -> S.SerialT m Int) -> Int -> m ()
toNull t start = runStream . t $ do
x <- source start prodCount
y <- source start prodCount
return $ x * x + y * y
{-# INLINE toList #-}
toList
:: (S.IsStream t, Monad m, Monad (t m))
=> (t m Int -> S.SerialT m Int) -> Int -> m [Int]
toList t start = runToList . t $ do
x <- source start prodCount
y <- source start prodCount
return $ x * x + y * y
{-# INLINE toListSome #-}
toListSome
:: (S.IsStream t, Monad m, Monad (t m))
=> (t m Int -> S.SerialT m Int) -> Int -> m [Int]
toListSome t start =
runToList . t $ S.take 1000 $ do
x <- source start prodCount
y <- source start prodCount
return $ x * x + y * y
{-# INLINE filterAllOut #-}
filterAllOut
:: (S.IsStream t, Monad m, Monad (t m))
=> (t m Int -> S.SerialT m Int) -> Int -> m ()
filterAllOut t start = runStream . t $ do
x <- source start prodCount
y <- source start prodCount
let s = x * x + y * y
if (s < 1)
then return s
else S.nil
{-# INLINE filterAllIn #-}
filterAllIn
:: (S.IsStream t, Monad m, Monad (t m))
=> (t m Int -> S.SerialT m Int) -> Int -> m ()
filterAllIn t start = runStream . t $ do
x <- source start prodCount
y <- source start prodCount
let s = x * x + y * y
if (s > 1)
then return s
else S.nil
{-# INLINE filterSome #-}
filterSome
:: (S.IsStream t, Monad m, Monad (t m))
=> (t m Int -> S.SerialT m Int) -> Int -> m ()
filterSome t start = runStream . t $ do
x <- source start prodCount
y <- source start prodCount
let s = x * x + y * y
if (s > 1100000)
then return s
else S.nil
{-# INLINE breakAfterSome #-}
breakAfterSome
:: (S.IsStream t, Monad (t IO))
=> (t IO Int -> S.SerialT IO Int) -> Int -> IO ()
breakAfterSome t start = do
(_ :: Either ErrorCall ()) <- try $ runStream . t $ do
x <- source start prodCount
y <- source start prodCount
let s = x * x + y * y
if (s > 1100000)
then error "break"
else return s
return ()