on 6006084 help sign in
242 lines 7.4 kB history raw
1-- |
2-- Module : Streamly.Benchmark.Data.ArrayOps
3-- Copyright : (c) 2020 Composewell Technologies
4--
5-- License : BSD-3-Clause
6-- Maintainer : streamly@composewell.com
8{-# LANGUAGE CPP #-}
9{-# LANGUAGE FlexibleContexts #-}
10{-# LANGUAGE ScopedTypeVariables #-}
12-- CPP:
13-- MEMORY_ARRAY
14-- DATA_ARRAY
15-- DATA_ARRAY_PRIM
16-- DATA_ARRAY_PRIM_PINNED
17-- DATA_SMALLARRAY
19module Streamly.Benchmark.Data.ArrayOps where
21import Control.Monad.IO.Class (MonadIO)
22import Prelude (Bool, Int, Maybe(..), ($), (+), (.), (==), (>), undefined)
24import qualified Prelude as P
25import qualified Streamly.Prelude as S
27#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
28#ifdef DEVBUILD
29import qualified Data.Foldable as F
30#endif
31#endif
33#ifdef DATA_SMALLARRAY
34import qualified Streamly.Internal.Data.SmallArray as A
35type Stream = A.SmallArray
36#elif defined(MEMORY_ARRAY)
37import qualified GHC.Exts as GHC
38import qualified Streamly.Data.Array.Foreign as A
39import qualified Streamly.Internal.Data.Array.Foreign as A
40type Stream = A.Array
41#elif defined(DATA_ARRAY_PRIM)
42import qualified Streamly.Internal.Data.Array.Prim as A
43type Stream = A.Array
44#elif defined(DATA_ARRAY_PRIM_PINNED)
45import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
46type Stream = A.Array
47#elif defined(DATA_ARRAY)
48import qualified Streamly.Internal.Data.Array as A
49type Stream = A.Array
50#endif
52-------------------------------------------------------------------------------
53-- Benchmark ops
54-------------------------------------------------------------------------------
56-------------------------------------------------------------------------------
57-- Stream generation and elimination
58-------------------------------------------------------------------------------
60-------------------------------------------------------------------------------
61-- CPP Common to:
62-- MEMORY_ARRAY
63-- DATA_ARRAY
64-- DATA_ARRAY_PRIM
65-- DATA_ARRAY_PRIM_PINNED
66-- DATA_SMALLARRAY
67-------------------------------------------------------------------------------
69{-# INLINE sourceUnfoldr #-}
70sourceUnfoldr :: MonadIO m => Int -> Int -> m (Stream Int)
71sourceUnfoldr value n = S.fold (A.writeN value) $ S.unfoldr step n
72 where
73 step cnt =
74 if cnt > n + value
75 then Nothing
76 else (Just (cnt, cnt + 1))
78{-# INLINE sourceIntFromTo #-}
79sourceIntFromTo :: MonadIO m => Int -> Int -> m (Stream Int)
80sourceIntFromTo value n = S.fold (A.writeN value) $ S.enumerateFromTo n (n + value)
82{-# INLINE sourceFromList #-}
83sourceFromList :: MonadIO m => Int -> Int -> m (Stream Int)
84sourceFromList value n = S.fold (A.writeN value) $ S.fromList [n..n+value]
86-- Different defination of sourceIntFromToFromList for DATA_SMALLARRAY
87-- CPP:
88{-# INLINE sourceIntFromToFromList #-}
89sourceIntFromToFromList :: MonadIO m => Int -> Int -> m (Stream Int)
90#ifndef DATA_SMALLARRAY
91sourceIntFromToFromList value n = P.return $ A.fromList $ [n..n + value]
92#else
93sourceIntFromToFromList value n = P.return $ A.fromListN value $ [n..n + value]
94#endif
96-------------------------------------------------------------------------------
97-- CPP Common to:
98-- MEMORY_ARRAY
99-- DATA_ARRAY
100-- DATA_ARRAY_PRIM
101-- DATA_ARRAY_PRIM_PINNED
102-------------------------------------------------------------------------------
104-- CPP:
105#ifndef DATA_SMALLARRAY
106{-# INLINE sourceIntFromToFromStream #-}
107sourceIntFromToFromStream :: MonadIO m => Int -> Int -> m (Stream Int)
108sourceIntFromToFromStream value n = S.fold A.write $ S.enumerateFromTo n (n + value)
109#endif
111-------------------------------------------------------------------------------
112-- CPP Common to:
113-- MEMORY_ARRAY
114-------------------------------------------------------------------------------
116-- CPP:
117#ifdef MEMORY_ARRAY
118{-# INLINE sourceIsList #-}
119sourceIsList :: Int -> Int -> Stream Int
120sourceIsList value n = GHC.fromList [n..n+value]
122{-# INLINE sourceIsString #-}
123sourceIsString :: Int -> Int -> Stream P.Char
124sourceIsString value n = GHC.fromString (P.replicate (n + value) 'a')
125#endif
127-------------------------------------------------------------------------------
128-- Transformation
129-------------------------------------------------------------------------------
131-------------------------------------------------------------------------------
132-- CPP Common to:
133-- MEMORY_ARRAY
134-- DATA_ARRAY
135-- DATA_ARRAY_PRIM
136-- DATA_ARRAY_PRIM_PINNED
137-- DATA_SMALLARRAY
138-------------------------------------------------------------------------------
140{-# INLINE composeN #-}
141composeN :: P.Monad m
142 => Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
143composeN n f x =
144 case n of
145 1 -> f x
146 2 -> f x P.>>= f
147 3 -> f x P.>>= f P.>>= f
148 4 -> f x P.>>= f P.>>= f P.>>= f
149 _ -> undefined
151{-# INLINE scanl' #-}
152{-# INLINE scanl1' #-}
153{-# INLINE map #-}
155scanl' , scanl1', map
156 :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
159{-# INLINE onArray #-}
160onArray
161 :: MonadIO m => Int -> (S.SerialT m Int -> S.SerialT m Int)
162 -> Stream Int
163 -> m (Stream Int)
164onArray value f arr = S.fold (A.writeN value) $ f $ (S.unfold A.read arr)
166scanl' value n = composeN n $ onArray value $ S.scanl' (+) 0
167scanl1' value n = composeN n $ onArray value $ S.scanl1' (+)
168map value n = composeN n $ onArray value $ S.map (+1)
169-- map n = composeN n $ A.map (+1)
171{-# INLINE eqInstance #-}
172eqInstance :: Stream Int -> Bool
173eqInstance src = src == src
175{-# INLINE eqInstanceNotEq #-}
176eqInstanceNotEq :: Stream Int -> Bool
177eqInstanceNotEq src = src P./= src
179{-# INLINE ordInstance #-}
180ordInstance :: Stream Int -> Bool
181ordInstance src = src P.< src
183{-# INLINE ordInstanceMin #-}
184ordInstanceMin :: Stream Int -> Stream Int
185ordInstanceMin src = P.min src src
187{-# INLINE showInstance #-}
188showInstance :: Stream Int -> P.String
189showInstance src = P.show src
191{-# INLINE pureFoldl' #-}
192pureFoldl' :: MonadIO m => Stream Int -> m Int
193pureFoldl' = S.foldl' (+) 0 . S.unfold A.read
195-------------------------------------------------------------------------------
196-- CPP Common to:
197-- MEMORY_ARRAY
198-- DATA_ARRAY
199-- DATA_SMALLARRAY
200-------------------------------------------------------------------------------
202-- CPP:
203#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
204{-# INLINE readInstance #-}
205readInstance :: P.String -> Stream Int
206readInstance str =
207 let r = P.reads str
208 in case r of
209 [(x,"")] -> x
210 _ -> P.error "readInstance: no parse"
212#ifdef DEVBUILD
213{-# INLINE foldableFoldl' #-}
214foldableFoldl' :: Stream Int -> Int
215foldableFoldl' = F.foldl' (+) 0
217{-# INLINE foldableSum #-}
218foldableSum :: Stream Int -> Int
219foldableSum = P.sum
220#endif
221#endif
223-------------------------------------------------------------------------------
224-- Elimination
225-------------------------------------------------------------------------------
227-------------------------------------------------------------------------------
228-- CPP Common to:
229-- MEMORY_ARRAY
230-- DATA_ARRAY
231-- DATA_ARRAY_PRIM
232-- DATA_ARRAY_PRIM_PINNED
233-- DATA_SMALLARRAY
234-------------------------------------------------------------------------------
236{-# INLINE unfoldReadDrain #-}
237unfoldReadDrain :: MonadIO m => Stream Int -> m ()
238unfoldReadDrain = S.drain . S.unfold A.read
240{-# INLINE toStreamRevDrain #-}
241toStreamRevDrain :: MonadIO m => Stream Int -> m ()
242toStreamRevDrain = S.drain . A.toStreamRev