on d2cde55 help sign in
246 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
29{-
30import qualified Data.Foldable as F
31-}
32#endif
33#endif
35#ifdef DATA_SMALLARRAY
36import qualified Streamly.Internal.Data.SmallArray as A
37type Stream = A.SmallArray
38#elif defined(MEMORY_ARRAY)
39import qualified GHC.Exts as GHC
40import qualified Streamly.Data.Array.Foreign as A
41import qualified Streamly.Internal.Data.Array.Foreign as A
42type Stream = A.Array
43#elif defined(DATA_ARRAY_PRIM)
44import qualified Streamly.Internal.Data.Array.Prim as A
45type Stream = A.Array
46#elif defined(DATA_ARRAY_PRIM_PINNED)
47import qualified Streamly.Internal.Data.Array.Prim.Pinned as A
48type Stream = A.Array
49#elif defined(DATA_ARRAY)
50import qualified Streamly.Internal.Data.Array as A
51type Stream = A.Array
52#endif
54-------------------------------------------------------------------------------
55-- Benchmark ops
56-------------------------------------------------------------------------------
58-------------------------------------------------------------------------------
59-- Stream generation and elimination
60-------------------------------------------------------------------------------
62-------------------------------------------------------------------------------
63-- CPP Common to:
64-- MEMORY_ARRAY
65-- DATA_ARRAY
66-- DATA_ARRAY_PRIM
67-- DATA_ARRAY_PRIM_PINNED
68-- DATA_SMALLARRAY
69-------------------------------------------------------------------------------
71{-# INLINE sourceUnfoldr #-}
72sourceUnfoldr :: MonadIO m => Int -> Int -> m (Stream Int)
73sourceUnfoldr value n = S.fold (A.writeN value) $ S.unfoldr step n
74 where
75 step cnt =
76 if cnt > n + value
77 then Nothing
78 else (Just (cnt, cnt + 1))
80{-# INLINE sourceIntFromTo #-}
81sourceIntFromTo :: MonadIO m => Int -> Int -> m (Stream Int)
82sourceIntFromTo value n = S.fold (A.writeN value) $ S.enumerateFromTo n (n + value)
84{-# INLINE sourceFromList #-}
85sourceFromList :: MonadIO m => Int -> Int -> m (Stream Int)
86sourceFromList value n = S.fold (A.writeN value) $ S.fromList [n..n+value]
88-- Different defination of sourceIntFromToFromList for DATA_SMALLARRAY
89-- CPP:
90{-# INLINE sourceIntFromToFromList #-}
91sourceIntFromToFromList :: MonadIO m => Int -> Int -> m (Stream Int)
92#ifndef DATA_SMALLARRAY
93sourceIntFromToFromList value n = P.return $ A.fromList $ [n..n + value]
94#else
95sourceIntFromToFromList value n = P.return $ A.fromListN value $ [n..n + value]
96#endif
98-------------------------------------------------------------------------------
99-- CPP Common to:
100-- MEMORY_ARRAY
101-- DATA_ARRAY
102-- DATA_ARRAY_PRIM
103-- DATA_ARRAY_PRIM_PINNED
104-------------------------------------------------------------------------------
106-- CPP:
107#ifndef DATA_SMALLARRAY
108{-# INLINE sourceIntFromToFromStream #-}
109sourceIntFromToFromStream :: MonadIO m => Int -> Int -> m (Stream Int)
110sourceIntFromToFromStream value n = S.fold A.write $ S.enumerateFromTo n (n + value)
111#endif
113-------------------------------------------------------------------------------
114-- CPP Common to:
115-- MEMORY_ARRAY
116-------------------------------------------------------------------------------
118-- CPP:
119#ifdef MEMORY_ARRAY
120{-# INLINE sourceIsList #-}
121sourceIsList :: Int -> Int -> Stream Int
122sourceIsList value n = GHC.fromList [n..n+value]
124{-# INLINE sourceIsString #-}
125sourceIsString :: Int -> Int -> Stream P.Char
126sourceIsString value n = GHC.fromString (P.replicate (n + value) 'a')
127#endif
129-------------------------------------------------------------------------------
130-- Transformation
131-------------------------------------------------------------------------------
133-------------------------------------------------------------------------------
134-- CPP Common to:
135-- MEMORY_ARRAY
136-- DATA_ARRAY
137-- DATA_ARRAY_PRIM
138-- DATA_ARRAY_PRIM_PINNED
139-- DATA_SMALLARRAY
140-------------------------------------------------------------------------------
142{-# INLINE composeN #-}
143composeN :: P.Monad m
144 => Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
145composeN n f x =
146 case n of
147 1 -> f x
148 2 -> f x P.>>= f
149 3 -> f x P.>>= f P.>>= f
150 4 -> f x P.>>= f P.>>= f P.>>= f
151 _ -> undefined
153{-# INLINE scanl' #-}
154{-# INLINE scanl1' #-}
155{-# INLINE map #-}
157scanl' , scanl1', map
158 :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
161{-# INLINE onArray #-}
162onArray
163 :: MonadIO m => Int -> (S.SerialT m Int -> S.SerialT m Int)
164 -> Stream Int
165 -> m (Stream Int)
166onArray value f arr = S.fold (A.writeN value) $ f $ (S.unfold A.read arr)
168scanl' value n = composeN n $ onArray value $ S.scanl' (+) 0
169scanl1' value n = composeN n $ onArray value $ S.scanl1' (+)
170map value n = composeN n $ onArray value $ S.map (+1)
171-- map n = composeN n $ A.map (+1)
173{-# INLINE eqInstance #-}
174eqInstance :: Stream Int -> Bool
175eqInstance src = src == src
177{-# INLINE eqInstanceNotEq #-}
178eqInstanceNotEq :: Stream Int -> Bool
179eqInstanceNotEq src = src P./= src
181{-# INLINE ordInstance #-}
182ordInstance :: Stream Int -> Bool
183ordInstance src = src P.< src
185{-# INLINE ordInstanceMin #-}
186ordInstanceMin :: Stream Int -> Stream Int
187ordInstanceMin src = P.min src src
189{-# INLINE showInstance #-}
190showInstance :: Stream Int -> P.String
191showInstance src = P.show src
193{-# INLINE pureFoldl' #-}
194pureFoldl' :: MonadIO m => Stream Int -> m Int
195pureFoldl' = S.foldl' (+) 0 . S.unfold A.read
197-------------------------------------------------------------------------------
198-- CPP Common to:
199-- MEMORY_ARRAY
200-- DATA_ARRAY
201-- DATA_SMALLARRAY
202-------------------------------------------------------------------------------
204-- CPP:
205#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
206{-# INLINE readInstance #-}
207readInstance :: P.String -> Stream Int
208readInstance str =
209 let r = P.reads str
210 in case r of
211 [(x,"")] -> x
212 _ -> P.error "readInstance: no parse"
214#ifdef DEVBUILD
215{-
216{-# INLINE foldableFoldl' #-}
217foldableFoldl' :: Stream Int -> Int
218foldableFoldl' = F.foldl' (+) 0
220{-# INLINE foldableSum #-}
221foldableSum :: Stream Int -> Int
222foldableSum = P.sum
223-}
224#endif
225#endif
227-------------------------------------------------------------------------------
228-- Elimination
229-------------------------------------------------------------------------------
231-------------------------------------------------------------------------------
232-- CPP Common to:
233-- MEMORY_ARRAY
234-- DATA_ARRAY
235-- DATA_ARRAY_PRIM
236-- DATA_ARRAY_PRIM_PINNED
237-- DATA_SMALLARRAY
238-------------------------------------------------------------------------------
240{-# INLINE unfoldReadDrain #-}
241unfoldReadDrain :: MonadIO m => Stream Int -> m ()
242unfoldReadDrain = S.drain . S.unfold A.read
244{-# INLINE toStreamRevDrain #-}
245toStreamRevDrain :: MonadIO m => Stream Int -> m ()
246toStreamRevDrain = S.drain . A.toStreamRev