packages feed

streamly-0.11.0: benchmark/Streamly/Benchmark/Data/Stream/Rate.hs

{-# LANGUAGE FlexibleContexts #-}

-- |
-- Module      : Main
-- Copyright   : (c) 2018 Composewell Technologies
--
-- License     : BSD3
-- Maintainer  : streamly@composewell.com

import Stream.Common (benchIOSrc, sourceUnfoldrM)
import Streamly.Data.Stream (Stream)
import Streamly.Internal.Data.Stream.Prelude (MonadAsync, Config)

import qualified Streamly.Data.Stream.Prelude as Stream

import Streamly.Benchmark.Common
import Test.Tasty.Bench

moduleName :: String
moduleName = "Data.Stream.Rate"

-------------------------------------------------------------------------------
-- Average Rate
-------------------------------------------------------------------------------

{-# INLINE rateNothing #-}
rateNothing :: MonadAsync m =>
    ((Config -> Config) -> Stream m Int -> Stream m Int)
    -> (Config -> Config) -> Int -> Int -> Stream m Int
rateNothing f cfg value = f (Stream.rate Nothing . cfg) . sourceUnfoldrM value

{-# INLINE avgRate #-}
avgRate :: MonadAsync m =>
    ((Config -> Config) -> Stream m Int -> Stream m Int)
    -> (Config -> Config) -> Int -> Double -> Int -> Stream m Int
avgRate f cfg value rt = f (Stream.avgRate rt . cfg) . sourceUnfoldrM value

{-
-- parBuffered should be maxThreads 1 anyway
{-# INLINE avgRateThreads1 #-}
avgRateThreads1 :: MonadAsync m =>
    ((Config -> Config) -> Stream m Int -> Stream m Int)
    -> (Config -> Config) -> Int -> Double -> Int -> Stream m Int
avgRateThreads1 f cfg value rt =
    f (Stream.maxThreads 1 . Stream.avgRate rt . cfg) . sourceUnfoldrM value
-}

{-# INLINE minRate #-}
minRate :: MonadAsync m =>
    ((Config -> Config) -> Stream m Int -> Stream m Int)
    -> (Config -> Config) -> Int -> Double -> Int -> Stream m Int
minRate f cfg value rt = f (Stream.minRate rt . cfg) . sourceUnfoldrM value

{-# INLINE maxRate #-}
maxRate :: MonadAsync m =>
    ((Config -> Config) -> Stream m Int -> Stream m Int)
    -> (Config -> Config) -> Int -> Double -> Int -> Stream m Int
maxRate f cfg value rt = f (Stream.minRate rt . cfg) . sourceUnfoldrM value

{-# INLINE constRate #-}
constRate :: MonadAsync m =>
    ((Config -> Config) -> Stream m Int -> Stream m Int)
    -> (Config -> Config) -> Int -> Double -> Int -> Stream m Int
constRate f cfg value rt = f (Stream.constRate rt . cfg) . sourceUnfoldrM value

-- XXX arbitrarily large rate should be the same as rate Nothing
-- XXX Add tests for multiworker cases as well - parMapM
o_1_space_async :: Int -> [Benchmark]
o_1_space_async value =
    [ bgroup
          "default/parBuffered"
          [ bgroup
                "avgRate"
                -- benchIO "unfoldr" $ toNull
                [ benchIOSrc "baseline" (Stream.parBuffered id . sourceUnfoldrM value)
                , benchIOSrc "Nothing" $ rateNothing Stream.parBuffered id value
                , benchIOSrc "1M" $ avgRate Stream.parBuffered id value 1000000
                , benchIOSrc "3M" $ avgRate Stream.parBuffered id value 3000000
                -- , benchIOSrc "10M/maxThreads1" $ avgRateThreads1 Stream.parBuffered value 10000000
                , benchIOSrc "10M" $ avgRate Stream.parBuffered id value 10000000
                , benchIOSrc "20M" $ avgRate Stream.parBuffered id value 20000000
                ]
          , bgroup
                "minRate"
                [ benchIOSrc "1M" $ minRate Stream.parBuffered id value 1000000
                , benchIOSrc "10M" $ minRate Stream.parBuffered id value 10000000
                , benchIOSrc "20M" $ minRate Stream.parBuffered id value 20000000
                ]
          , bgroup
                "maxRate"
                [ -- benchIOSrc "10K" $ maxRate value 10000
                  benchIOSrc "10M" $ maxRate Stream.parBuffered id value 10000000
                ]
          , bgroup
                "constRate"
                [ -- benchIOSrc "10K" $ constRate value 10000
                  benchIOSrc "1M" $ constRate Stream.parBuffered id value 1000000
                , benchIOSrc "10M" $ constRate Stream.parBuffered id value 10000000
                ]
          ]
    ]

o_1_space_ahead :: Int -> [Benchmark]
o_1_space_ahead value =
    [ bgroup
        "ordered/parBuffered"
        [ benchIOSrc "avgRate/1M"
            $ avgRate Stream.parBuffered (Stream.ordered True) value 1000000
        , benchIOSrc "minRate/1M"
            $ minRate Stream.parBuffered (Stream.ordered True) value 1000000
        , benchIOSrc "maxRate/1M"
            $ maxRate Stream.parBuffered (Stream.ordered True) value 1000000
        , benchIOSrc "constRate/1M"
            $ constRate Stream.parBuffered (Stream.ordered True) value 1000000
        ]
    ]

-------------------------------------------------------------------------------
-- Main
-------------------------------------------------------------------------------

main :: IO ()
main = runWithCLIOpts defaultStreamSize allBenchmarks

    where

    allBenchmarks value =
        [ bgroup (o_1_space_prefix moduleName)
        $ concat [o_1_space_async value, o_1_space_ahead value]]