on master help sign in
Round up space to 4K for large objects
a096f77Harendra Kumar
src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+21−11
@@ -29,7 +29,7 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
29
29
30 -- * Resizing
30 -- * Resizing
31 , realloc
31 , realloc
32− , shrinkToFit
32+ , rightSize
33
33
34 -- * Size
34 -- * Size
35 , length
35 , length
@@ -533,18 +533,28 @@ realloc i arr =
533 $ reallocAligned
533 $ reallocAligned
534 (sizeOf (undefined :: a)) (alignment (undefined :: a)) i arr
534 (sizeOf (undefined :: a)) (alignment (undefined :: a)) i arr
535
535
536−-- | Remove the free space from an Array.
536+-- | Drop any reserved free space at the end of the array and reallocate it to
537−{-# INLINE shrinkToFit #-}
537+-- reduce wastage.
538+--
539+-- Up to 25% wastage is allowed to avoid reallocations. If the capacity is
540+-- more than 'largeObjectThreshold' then free space up to the 'blockSize' is
541+-- retained.
542+--
543+-- /Pre-release/
544+{-# INLINE rightSize #-}
538−shrinkToFit :: (MonadIO m, Storable a) => Array a -> m (Array a)
545+rightSize :: forall m a. (MonadIO m, Storable a) => Array a -> m (Array a)
539−shrinkToFit arr@Array{..} = do
546+rightSize arr@Array{..} = do
540 assert (aEnd <= aBound) (return ())
547 assert (aEnd <= aBound) (return ())
541 let start = unsafeForeignPtrToPtr aStart
548 let start = unsafeForeignPtrToPtr aStart
542− let used = aEnd `minusPtr` start
549+ len = aEnd `minusPtr` start
550+ capacity = aBound `minusPtr` start
551+ target = roundUpLargeArray len
543 waste = aBound `minusPtr` aEnd
552 waste = aBound `minusPtr` aEnd
544− -- if used == waste == 0 then do not realloc
553+ assert (target >= len) (return ())
545− -- if the wastage is more than 25% of the array then realloc
554+ assert (len `mod` sizeOf (undefined :: a) == 0) (return ())
555+ -- We trade off some wastage (25%) to avoid reallocations and copying.
546− if used < 3 * waste
556+ if target < capacity && len < 3 * waste
547− then realloc used arr
557+ then realloc target arr
548 else return arr
558 else return arr
549
559
550-------------------------------------------------------------------------------
560-------------------------------------------------------------------------------
@@ -1106,7 +1116,7 @@ writeWith alignSize elemCount =
1106 (sizeOf (undefined :: a)) alignSize newSize arr
1116 (sizeOf (undefined :: a)) alignSize newSize arr
1107 insertElem arr1 x
1117 insertElem arr1 x
1108 step arr x = insertElem arr x
1118 step arr x = insertElem arr x
1109− extract = liftIO . shrinkToFit
1119+ extract = liftIO . rightSize
1110
1120
1111-- | Fold the whole input to a single array.
1121-- | Fold the whole input to a single array.
1112--
1122--
src/Streamly/Internal/Data/Array/Foreign/Type.hs+2−2
@@ -170,12 +170,12 @@ foreign import ccall unsafe "string.h strlen" c_strlen
170unsafeFreeze :: MA.Array a -> Array a
170unsafeFreeze :: MA.Array a -> Array a
171unsafeFreeze (MA.Array as ae _) = Array as ae
171unsafeFreeze (MA.Array as ae _) = Array as ae
172
172
173−-- | Similar to 'unsafeFreeze' but uses 'MA.shrinkToFit' on the mutable array
173+-- | Similar to 'unsafeFreeze' but uses 'MA.rightSize' on the mutable array
174-- first.
174-- first.
175{-# INLINE unsafeFreezeWithShrink #-}
175{-# INLINE unsafeFreezeWithShrink #-}
176unsafeFreezeWithShrink :: Storable a => MA.Array a -> Array a
176unsafeFreezeWithShrink :: Storable a => MA.Array a -> Array a
177unsafeFreezeWithShrink arr = unsafePerformIO $ do
177unsafeFreezeWithShrink arr = unsafePerformIO $ do
178− MA.Array as ae _ <- MA.shrinkToFit arr
178+ MA.Array as ae _ <- MA.rightSize arr
179 return $ Array as ae
179 return $ Array as ae
180
180
181-- | Makes a mutable array using the underlying memory of the immutable array.
181-- | Makes a mutable array using the underlying memory of the immutable array.
src/Streamly/Internal/Data/Array/Stream/Foreign.hs+1−1
@@ -474,7 +474,7 @@ spliceArraysRealloced s = do
474 (mkChunkSizeKB 4))
474 (mkChunkSizeKB 4))
475
475
476 arr <- S.foldlM' MA.spliceExp idst (S.map A.unsafeThaw s)
476 arr <- S.foldlM' MA.spliceExp idst (S.map A.unsafeThaw s)
477− liftIO $ A.unsafeFreeze <$> MA.shrinkToFit arr
477+ liftIO $ A.unsafeFreeze <$> MA.rightSize arr
478
478
479-- XXX This should just be "fold A.write"
479-- XXX This should just be "fold A.write"
480--
480--