on master help sign in
Move eq, cmp impl to mutable module

Add INLINE in instances Implement instances in terms of mutable array ops

commit5598e505c03b5a7a038bc44fa9a2ee9aa287673f authorHarendra Kumar <harendra@composewell.com> dateFri 10 Mar 2023, 20:25 (4 years ago) parent8d9a164
3 files changed+97−34
core/src/Streamly/Internal/Data/Array/Generic.hs+30−31 core/src/Streamly/Internal/Data/Array/Generic/Mut/Type.hs+65−2 core/src/Streamly/Internal/Data/Array/Mut/Type.hs+2−1
core/src/Streamly/Internal/Data/Array/Generic.hs+30−31
@@ -217,6 +217,7 @@ writeLastN n = FL.rmapM f (RB.writeLastN n)
217217 arr <- RB.toMutArray 0 n rb
218218 return $ unsafeFreeze arr
219219
220+{-# INLINE sliceUnsafe #-}
220221sliceUnsafe :: Int -> Int -> Array a -> Array a
221222sliceUnsafe offset len (Array cont off1 _) = Array cont (off1 + offset) len
222223
@@ -226,6 +227,7 @@ sliceUnsafe offset len (Array cont off1 _) = Array cont (off1 + offset) len
226227
227228-- | Truncate the array at the beginning and end as long as the predicate
228229-- holds true. Returns a slice of the original array.
230+{-# INLINE strip #-}
229231strip :: (a -> Bool) -> Array a -> Array a
230232strip p arr =
231233 let lastIndex = length arr - 1
@@ -259,46 +261,43 @@ strip p arr =
259261-------------------------------------------------------------------------------
260262
261263instance Eq a => Eq (Array a) where
262− a1 == a2 = lenA1 == lenA2 && loop (lenA1 - 1)
264+ {-# INLINE (==) #-}
265+ arr1 == arr2 =
266+ unsafeInlineIO $! unsafeThaw arr1 `MArray.eq` unsafeThaw arr2
263267
264− where
268+instance Ord a => Ord (Array a) where
269+ {-# INLINE compare #-}
270+ compare arr1 arr2 =
271+ unsafeInlineIO $! unsafeThaw arr1 `MArray.cmp` unsafeThaw arr2
265272
266− lenA1 = length a1
267− lenA2 = length a2
273+ -- Default definitions defined in base do not have an INLINE on them, so we
274+ -- replicate them here with an INLINE.
275+ {-# INLINE (<) #-}
276+ x < y = case compare x y of { LT -> True; _ -> False }
268277
269− loop i
270− | i < 0 = True
271− | otherwise =
272− let v1 = getIndexUnsafe i a1
273− v2 = getIndexUnsafe i a2
274− in v1 == v2 && loop (i - 1)
278+ {-# INLINE (<=) #-}
279+ x <= y = case compare x y of { GT -> False; _ -> True }
275280
276−instance Ord a => Ord (Array a) where
277− compare a1 a2 =
278− case compare lenA1 lenA2 of
279− LT -> LT
280− GT -> GT
281− EQ -> loop 0
282−
283− where
284−
285− lenA1 = length a1
286− lenA2 = length a2
287−
288− loop i
289− | i >= lenA1 = EQ
290− | otherwise =
291− let v1 = getIndexUnsafe i a1
292− v2 = getIndexUnsafe i a2
293− in case compare v1 v2 of
294− LT -> LT
295− GT -> GT
296− EQ -> loop (i + 1)
281+ {-# INLINE (>) #-}
282+ x > y = case compare x y of { GT -> True; _ -> False }
283+
284+ {-# INLINE (>=) #-}
285+ x >= y = case compare x y of { LT -> False; _ -> True }
286+
287+ -- These two default methods use '<=' rather than 'compare'
288+ -- because the latter is often more expensive
289+ {-# INLINE max #-}
290+ max x y = if x <= y then y else x
291+
292+ {-# INLINE min #-}
293+ min x y = if x <= y then x else y
297294
298295instance Show a => Show (Array a) where
296+ {-# INLINE show #-}
299297 show arr = "fromList " ++ show (toList arr)
300298
301299instance Read a => Read (Array a) where
300+ {-# INLINE readPrec #-}
302301 readPrec = do
303302 fromListWord <- replicateM 9 ReadPrec.get
304303 if fromListWord == "fromList "
core/src/Streamly/Internal/Data/Array/Generic/Mut/Type.hs+65−2
@@ -104,6 +104,9 @@ module Streamly.Internal.Data.Array.Generic.Mut.Type
104104 -- , getFromThenTo
105105 -- , getIndexRev
106106
107+ -- * Size
108+ , length
109+
107110 -- * In-place Mutation Algorithms
108111 -- , reverse
109112 -- , permute
@@ -115,7 +118,8 @@ module Streamly.Internal.Data.Array.Generic.Mut.Type
115118 -- * Folding
116119 -- , foldl'
117120 -- , foldr
118− -- , cmp
121+ , cmp
122+ , eq
119123
120124 -- * Arrays of arrays
121125 -- We can add dimensionality parameter to the array type to get
@@ -181,7 +185,7 @@ import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
181185import qualified Streamly.Internal.Data.Stream.StreamD.Generate as D
182186import qualified Streamly.Internal.Data.Stream.StreamK.Type as K
183187
184−import Prelude hiding (read)
188+import Prelude hiding (read, length)
185189
186190-- $setup
187191-- >>> :m
@@ -703,3 +707,62 @@ clone src = liftIO $ do
703707 dst <- new len
704708 putSliceUnsafe src 0 dst 0 len
705709 return dst
710+
711+-------------------------------------------------------------------------------
712+-- Size
713+-------------------------------------------------------------------------------
714+
715+{-# INLINE length #-}
716+length :: MutArray a -> Int
717+length = arrLen
718+
719+-------------------------------------------------------------------------------
720+-- Equality
721+-------------------------------------------------------------------------------
722+
723+-- | Compare the length of the arrays. If the length is equal, compare the
724+-- lexicographical ordering of two underlying byte arrays otherwise return the
725+-- result of length comparison.
726+--
727+-- /Pre-release/
728+{-# INLINE cmp #-}
729+cmp :: (MonadIO m, Ord a) => MutArray a -> MutArray a -> m Ordering
730+cmp a1 a2 =
731+ case compare lenA1 lenA2 of
732+ EQ -> loop (lenA1 - 1)
733+ x -> return x
734+
735+ where
736+
737+ lenA1 = length a1
738+ lenA2 = length a2
739+
740+ loop i
741+ | i < 0 = return EQ
742+ | otherwise = do
743+ v1 <- getIndexUnsafe i a1
744+ v2 <- getIndexUnsafe i a2
745+ case compare v1 v2 of
746+ EQ -> loop (i - 1)
747+ x -> return x
748+
749+{-# INLINE eq #-}
750+eq :: (MonadIO m, Eq a) => MutArray a -> MutArray a -> m Bool
751+eq a1 a2 =
752+ if lenA1 == lenA2
753+ then loop (lenA1 - 1)
754+ else return False
755+
756+ where
757+
758+ lenA1 = length a1
759+ lenA2 = length a2
760+
761+ loop i
762+ | i < 0 = return True
763+ | otherwise = do
764+ v1 <- getIndexUnsafe i a1
765+ v2 <- getIndexUnsafe i a2
766+ if v1 == v2
767+ then loop (i - 1)
768+ else return False
core/src/Streamly/Internal/Data/Array/Mut/Type.hs+2−1
@@ -2250,7 +2250,8 @@ asPtrUnsafe arr f = do
22502250-------------------------------------------------------------------------------
22512251
22522252-- | Compare the length of the arrays. If the length is equal, compare the
2253−-- lexicographical ordering of two underlying byte arrays
2253+-- lexicographical ordering of two underlying byte arrays otherwise return the
2254+-- result of length comparison.
22542255--
22552256-- /Pre-release/
22562257{-# INLINE cmp #-}