mirror of
https://github.com/composewell/streamly.git
synced 2024-10-27 12:12:05 +03:00
247 lines
7.2 KiB
Haskell
247 lines
7.2 KiB
Haskell
-- |
|
|
-- Module : Streamly.Benchmark.Data.ArrayOps
|
|
-- Copyright : (c) 2020 Composewell Technologies
|
|
--
|
|
-- License : BSD-3-Clause
|
|
-- Maintainer : streamly@composewell.com
|
|
|
|
{-# LANGUAGE CPP #-}
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
-- CPP:
|
|
-- MEMORY_ARRAY
|
|
-- DATA_ARRAY
|
|
-- DATA_ARRAY_PRIM
|
|
-- DATA_ARRAY_PRIM_PINNED
|
|
-- DATA_SMALLARRAY
|
|
|
|
module Streamly.Benchmark.Data.ArrayOps where
|
|
|
|
import Control.Monad.IO.Class (MonadIO)
|
|
import Prelude (Bool, Int, Maybe(..), ($), (+), (.), (==), (>), undefined)
|
|
|
|
import qualified Prelude as P
|
|
import qualified Streamly.Prelude as S
|
|
|
|
#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
|
|
#ifdef DEVBUILD
|
|
{-
|
|
import qualified Data.Foldable as F
|
|
-}
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef DATA_SMALLARRAY
|
|
import qualified Streamly.Internal.Data.SmallArray as A
|
|
type Stream = A.SmallArray
|
|
#elif defined(MEMORY_ARRAY)
|
|
import qualified GHC.Exts as GHC
|
|
import qualified Streamly.Data.Array.Foreign as A
|
|
import qualified Streamly.Internal.Data.Array.Foreign as A
|
|
type Stream = A.Array
|
|
#elif defined(DATA_ARRAY_PRIM)
|
|
import qualified Streamly.Internal.Data.Array.Prim as A
|
|
type Stream = A.Array
|
|
#elif defined(DATA_ARRAY_PRIM_PINNED)
|
|
import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
|
|
type Stream = A.Array
|
|
#elif defined(DATA_ARRAY)
|
|
import qualified Streamly.Internal.Data.Array as A
|
|
type Stream = A.Array
|
|
#endif
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Benchmark ops
|
|
-------------------------------------------------------------------------------
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Stream generation and elimination
|
|
-------------------------------------------------------------------------------
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- CPP Common to:
|
|
-- MEMORY_ARRAY
|
|
-- DATA_ARRAY
|
|
-- DATA_ARRAY_PRIM
|
|
-- DATA_ARRAY_PRIM_PINNED
|
|
-- DATA_SMALLARRAY
|
|
-------------------------------------------------------------------------------
|
|
|
|
{-# INLINE sourceUnfoldr #-}
|
|
sourceUnfoldr :: MonadIO m => Int -> Int -> m (Stream Int)
|
|
sourceUnfoldr value n = S.fold (A.writeN value) $ S.unfoldr step n
|
|
where
|
|
step cnt =
|
|
if cnt > n + value
|
|
then Nothing
|
|
else (Just (cnt, cnt + 1))
|
|
|
|
{-# INLINE sourceIntFromTo #-}
|
|
sourceIntFromTo :: MonadIO m => Int -> Int -> m (Stream Int)
|
|
sourceIntFromTo value n = S.fold (A.writeN value) $ S.enumerateFromTo n (n + value)
|
|
|
|
{-# INLINE sourceFromList #-}
|
|
sourceFromList :: MonadIO m => Int -> Int -> m (Stream Int)
|
|
sourceFromList value n = S.fold (A.writeN value) $ S.fromList [n..n+value]
|
|
|
|
-- Different defination of sourceIntFromToFromList for DATA_SMALLARRAY
|
|
-- CPP:
|
|
{-# INLINE sourceIntFromToFromList #-}
|
|
sourceIntFromToFromList :: MonadIO m => Int -> Int -> m (Stream Int)
|
|
#ifndef DATA_SMALLARRAY
|
|
sourceIntFromToFromList value n = P.return $ A.fromList $ [n..n + value]
|
|
#else
|
|
sourceIntFromToFromList value n = P.return $ A.fromListN value $ [n..n + value]
|
|
#endif
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- CPP Common to:
|
|
-- MEMORY_ARRAY
|
|
-- DATA_ARRAY
|
|
-- DATA_ARRAY_PRIM
|
|
-- DATA_ARRAY_PRIM_PINNED
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- CPP:
|
|
#ifndef DATA_SMALLARRAY
|
|
{-# INLINE sourceIntFromToFromStream #-}
|
|
sourceIntFromToFromStream :: MonadIO m => Int -> Int -> m (Stream Int)
|
|
sourceIntFromToFromStream value n = S.fold A.write $ S.enumerateFromTo n (n + value)
|
|
#endif
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- CPP Common to:
|
|
-- MEMORY_ARRAY
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- CPP:
|
|
#ifdef MEMORY_ARRAY
|
|
{-# INLINE sourceIsList #-}
|
|
sourceIsList :: Int -> Int -> Stream Int
|
|
sourceIsList value n = GHC.fromList [n..n+value]
|
|
|
|
{-# INLINE sourceIsString #-}
|
|
sourceIsString :: Int -> Int -> Stream P.Char
|
|
sourceIsString value n = GHC.fromString (P.replicate (n + value) 'a')
|
|
#endif
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Transformation
|
|
-------------------------------------------------------------------------------
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- CPP Common to:
|
|
-- MEMORY_ARRAY
|
|
-- DATA_ARRAY
|
|
-- DATA_ARRAY_PRIM
|
|
-- DATA_ARRAY_PRIM_PINNED
|
|
-- DATA_SMALLARRAY
|
|
-------------------------------------------------------------------------------
|
|
|
|
{-# INLINE composeN #-}
|
|
composeN :: P.Monad m
|
|
=> Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
|
|
composeN n f x =
|
|
case n of
|
|
1 -> f x
|
|
2 -> f x P.>>= f
|
|
3 -> f x P.>>= f P.>>= f
|
|
4 -> f x P.>>= f P.>>= f P.>>= f
|
|
_ -> undefined
|
|
|
|
{-# INLINE scanl' #-}
|
|
{-# INLINE scanl1' #-}
|
|
{-# INLINE map #-}
|
|
|
|
scanl' , scanl1', map
|
|
:: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
|
|
|
|
|
|
{-# INLINE onArray #-}
|
|
onArray
|
|
:: MonadIO m => Int -> (S.SerialT m Int -> S.SerialT m Int)
|
|
-> Stream Int
|
|
-> m (Stream Int)
|
|
onArray value f arr = S.fold (A.writeN value) $ f $ (S.unfold A.read arr)
|
|
|
|
scanl' value n = composeN n $ onArray value $ S.scanl' (+) 0
|
|
scanl1' value n = composeN n $ onArray value $ S.scanl1' (+)
|
|
map value n = composeN n $ onArray value $ S.map (+1)
|
|
-- map n = composeN n $ A.map (+1)
|
|
|
|
{-# INLINE eqInstance #-}
|
|
eqInstance :: Stream Int -> Bool
|
|
eqInstance src = src == src
|
|
|
|
{-# INLINE eqInstanceNotEq #-}
|
|
eqInstanceNotEq :: Stream Int -> Bool
|
|
eqInstanceNotEq src = src P./= src
|
|
|
|
{-# INLINE ordInstance #-}
|
|
ordInstance :: Stream Int -> Bool
|
|
ordInstance src = src P.< src
|
|
|
|
{-# INLINE ordInstanceMin #-}
|
|
ordInstanceMin :: Stream Int -> Stream Int
|
|
ordInstanceMin src = P.min src src
|
|
|
|
{-# INLINE showInstance #-}
|
|
showInstance :: Stream Int -> P.String
|
|
showInstance src = P.show src
|
|
|
|
{-# INLINE pureFoldl' #-}
|
|
pureFoldl' :: MonadIO m => Stream Int -> m Int
|
|
pureFoldl' = S.foldl' (+) 0 . S.unfold A.read
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- CPP Common to:
|
|
-- MEMORY_ARRAY
|
|
-- DATA_ARRAY
|
|
-- DATA_SMALLARRAY
|
|
-------------------------------------------------------------------------------
|
|
|
|
-- CPP:
|
|
#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
|
|
{-# INLINE readInstance #-}
|
|
readInstance :: P.String -> Stream Int
|
|
readInstance str =
|
|
let r = P.reads str
|
|
in case r of
|
|
[(x,"")] -> x
|
|
_ -> P.error "readInstance: no parse"
|
|
|
|
#ifdef DEVBUILD
|
|
{-
|
|
{-# INLINE foldableFoldl' #-}
|
|
foldableFoldl' :: Stream Int -> Int
|
|
foldableFoldl' = F.foldl' (+) 0
|
|
|
|
{-# INLINE foldableSum #-}
|
|
foldableSum :: Stream Int -> Int
|
|
foldableSum = P.sum
|
|
-}
|
|
#endif
|
|
#endif
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Elimination
|
|
-------------------------------------------------------------------------------
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- CPP Common to:
|
|
-- MEMORY_ARRAY
|
|
-- DATA_ARRAY
|
|
-- DATA_ARRAY_PRIM
|
|
-- DATA_ARRAY_PRIM_PINNED
|
|
-- DATA_SMALLARRAY
|
|
-------------------------------------------------------------------------------
|
|
|
|
{-# INLINE unfoldReadDrain #-}
|
|
unfoldReadDrain :: MonadIO m => Stream Int -> m ()
|
|
unfoldReadDrain = S.drain . S.unfold A.read
|
|
|
|
{-# INLINE toStreamRevDrain #-}
|
|
toStreamRevDrain :: MonadIO m => Stream Int -> m ()
|
|
toStreamRevDrain = S.drain . A.toStreamRev
|