on master help sign in
Simplify array strip, improve perf
commitb8b410d23d2332a09691011eec70d9941a9dea23 authorHarendra Kumar <harendra@composewell.com> dateMon 14 Mar 2022, 02:27 (5 years ago) parentfaabb9a
2 files changed+38−46
benchmark/Streamly/Benchmark/Data/Array/Foreign/Mut.hs+4−18 core/src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+34−28
benchmark/Streamly/Benchmark/Data/Array/Foreign/Mut.hs+4−18
@@ -49,8 +49,8 @@ benchIO
4949benchIO name src sink =
5050 bench name $ nfIO $ randomRIO (1,1) >>= sink . src
5151
52−o_n_space_serial_marray :: Int -> MArray.Array Int -> [Benchmark]
53−o_n_space_serial_marray value array =
52+o_1_space_serial_marray :: Int -> MArray.Array Int -> [Benchmark]
53+o_1_space_serial_marray value array =
5454 [ benchIO "partitionBy (< 0)" (const array)
5555 $ MArray.partitionBy (< 0)
5656 , benchIO "partitionBy (> 0)" (const array)
@@ -59,22 +59,10 @@ o_n_space_serial_marray value array =
5959 $ MArray.partitionBy (< (value `div` 2))
6060 , benchIO "partitionBy (> value/2)" (const array)
6161 $ MArray.partitionBy (> (value `div` 2))
62− ]
63−
64−o_1_space_serial_marray :: Int -> MArray.Array Int -> [Benchmark]
65−o_1_space_serial_marray value array =
66− [ benchIO "strip (< 0)" (const array)
67− $ MArray.strip (< 0)
62+ , benchIO "strip (< value/2 || > value/2)" (const array)
63+ $ MArray.strip (\x -> x < value `div` 2 || x > value `div` 2)
6864 , benchIO "strip (> 0)" (const array)
6965 $ MArray.strip (> 0)
70− , benchIO "strip (< value/2)" (const array)
71− $ MArray.strip (< (value `div` 2))
72− , benchIO "strip (> value/2)" (const array)
73− $ MArray.strip (> (value `div` 2))
74− , benchIO "strip (odd)" (const array)
75− $ MArray.strip odd
76− , benchIO "strip (even)" (const array)
77− $ MArray.strip even
7866 ]
7967
8068-------------------------------------------------------------------------------
@@ -94,7 +82,5 @@ main = do
9482
9583 allBenchmarks array value =
9684 [ bgroup (o_1_space_prefix moduleName) $
97− o_n_space_serial_marray value array
98− , bgroup (o_1_space_prefix moduleName) $
9985 o_1_space_serial_marray value array
10086 ]
core/src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+34−28
@@ -135,6 +135,7 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
135135 , bytesFree
136136
137137 -- * In-place Mutation Algorithms
138+ , strip
138139 , reverse
139140 , permute
140141 , partitionBy
@@ -193,7 +194,6 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
193194 , memcpy
194195 , memcmp
195196 , c_memchr
196− , strip
197197 )
198198where
199199
@@ -2300,37 +2300,43 @@ instance NFData1 Array where
23002300-- | Strip elements which match with predicate from both ends.
23012301--
23022302-- /Pre-release/
2303+{-# INLINE strip #-}
23032304strip :: forall a m. (Storable a, MonadIO m) =>
23042305 (a -> Bool) -> Array a -> m (Array a)
23052306strip eq arr@Array{..} = do
2306− let p = arrStart
2307− q = aEnd
2308− len = length arr
2309− st <- liftIO $ getStart p len
2310− end <- liftIO $ do
2307+ st <- liftIO $ getStart arrStart
2308+ end <- liftIO $ getLast aEnd st
2309+ liftIO $ do
23112310 touch arrContents
2312− if st == q
2313− then return q
2314− else getLast $ PTR_PREV(q, a)
2315− go st end
2311+ return arr {arrStart = st, aEnd = end, aBound = end}
23162312
23172313 where
23182314
2319− getStart p i = do
2320− touch arrContents
2321− r <- peek p
2322− if eq r && i > 0
2323− then getStart (PTR_NEXT(p, a)) (i - 1)
2324− else return p
2325−
2326− getLast p = do
2327− touch arrContents
2328− r <- peek p
2329− if eq r
2330− then getLast $ PTR_PREV(p, a)
2331− else return $ PTR_NEXT(p, a)
2332−
2333− {-# INLINE go #-}
2334− go p q = liftIO $ do
2335− touch arrContents
2336− return arr {arrStart = p, aEnd = q, aBound = q}
2315+ {-
2316+ -- XXX This should have the same perf but it does not, investigate.
2317+ getStart = do
2318+ r <- liftIO $ D.head $ D.findIndices (not . eq) $ toStreamD arr
2319+ pure $
2320+ case r of
2321+ Nothing -> aEnd
2322+ Just i -> PTR_INDEX(arrStart,i,a)
2323+ -}
2324+
2325+ getStart cur = do
2326+ if cur < aEnd
2327+ then do
2328+ r <- peek cur
2329+ if eq r
2330+ then getStart (PTR_NEXT(cur, a))
2331+ else return cur
2332+ else return cur
2333+
2334+ getLast cur low = do
2335+ if cur > low
2336+ then do
2337+ let prev = PTR_PREV(cur,a)
2338+ r <- peek prev
2339+ if eq r
2340+ then getLast prev low
2341+ else return cur
2342+ else return cur