on master help sign in
Use roundUpToPower2 in snoc
37d3c17Harendra Kumar
src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+19−6
@@ -720,6 +720,7 @@ blockSize = 4 * 1024
720largeObjectThreshold :: Int
720largeObjectThreshold :: Int
721largeObjectThreshold = (blockSize * 8) `div` 10
721largeObjectThreshold = (blockSize * 8) `div` 10
722
722
723+-- XXX Should be done only when we are using the GHC allocator.
723-- | Round up an array larger than 'largeObjectThreshold' to use the whole
724-- | Round up an array larger than 'largeObjectThreshold' to use the whole
724-- block.
725-- block.
725{-# INLINE roundUpLargeArray #-}
726{-# INLINE roundUpLargeArray #-}
@@ -732,16 +733,23 @@ roundUpLargeArray size =
732 ((size + blockSize - 1) .&. negate blockSize)
733 ((size + blockSize - 1) .&. negate blockSize)
733 else size
734 else size
734
735
736+{-# INLINE isPower2 #-}
737+isPower2 :: Int -> Bool
738+isPower2 n = n .&. (n - 1) == 0
739+
740+{-# INLINE roundUpToPower2 #-}
735roundUpToPower2 :: Int -> Int
741roundUpToPower2 :: Int -> Int
736−roundUpToPower2 x =
742+roundUpToPower2 n =
737#if WORD_SIZE_IN_BITS == 64
743#if WORD_SIZE_IN_BITS == 64
738 1 + z6
744 1 + z6
739#else
745#else
740 1 + z5
746 1 + z5
741#endif
747#endif
748+
742 where
749 where
743− z = x - 1
750+
751+ z0 = n - 1
744− z1 = z .|. z `shiftR` 1
752+ z1 = z0 .|. z0 `shiftR` 1
745 z2 = z1 .|. z1 `shiftR` 2
753 z2 = z1 .|. z1 `shiftR` 2
746 z3 = z2 .|. z2 `shiftR` 4
754 z3 = z2 .|. z2 `shiftR` 4
747 z4 = z3 .|. z3 `shiftR` 8
755 z4 = z3 .|. z3 `shiftR` 8
@@ -1007,8 +1015,6 @@ snocWith allocSize arr x = liftIO $ do
1007snocLinear :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
1015snocLinear :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
1008snocLinear = snocWith (+ allocBytesToBytes (undefined :: a) arrayChunkBytes)
1016snocLinear = snocWith (+ allocBytesToBytes (undefined :: a) arrayChunkBytes)
1009
1017
1010−-- XXX round it to next power of 2.
1011−--
1012-- | The array is mutated to append an additional element to it. If there is no
1018-- | The array is mutated to append an additional element to it. If there is no
1013-- reserved space available in the array then it is reallocated to double the
1019-- reserved space available in the array then it is reallocated to double the
1014-- original size.
1020-- original size.
@@ -1025,7 +1031,14 @@ snocLinear = snocWith (+ allocBytesToBytes (undefined :: a) arrayChunkBytes)
1025-- /Pre-release/
1031-- /Pre-release/
1026{-# INLINE snoc #-}
1032{-# INLINE snoc #-}
1027snoc :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
1033snoc :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
1028−snoc = snocWith (* 2)
1034+snoc = snocWith f
1035+
1036+ where
1037+
1038+ f oldSize =
1039+ if isPower2 oldSize
1040+ then oldSize * 2
1041+ else roundUpToPower2 oldSize * 2
1029
1042
1030-------------------------------------------------------------------------------
1043-------------------------------------------------------------------------------
1031-- Random reads
1044-- Random reads