Skip to content

Commit

Permalink
Shave off a few int operations
Browse files Browse the repository at this point in the history
  • Loading branch information
chreekat committed Oct 4, 2023
1 parent aeeba2e commit 6528755
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/Data/Text/Internal/Reverse.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,47 @@ reverse ::
#endif
Text -> Text
#if defined(PURE_HASKELL)
reverse (Text ba off len) = runST $ do
reverse (Text src off len) = runST $ do
dest <- A.new len
_ <- reversePoints ba off dest (len - 1)
_ <- reversePoints src off dest len
result <- A.unsafeFreeze dest
pure $ Text result 0 len

-- Step 0:
--
-- Input: R E D R U M
-- ^
-- x
-- Output: _ _ _ _ _ _
-- ^
-- y
--
-- Step 1:
--
-- Input: R E D R U M
-- ^
-- x
--
-- Output: _ _ _ _ _ R
-- ^
-- y
reversePoints
:: A.Array -- ^ Input array
-> Int -- ^ Input index
-> A.MArray s -- ^ Output array
-> Int -- ^ Output index
-> ST s ()
reversePoints src x dest y = go x y where
go !_ pOut | pOut < 0 = pure ()
go pIn pOut =
let pointLength = utf8LengthByLeader (A.unsafeIndex src pIn)
pOut' = pOut - pointLength + 1
reversePoints src xx dest yy = go xx yy where
go !_ y | y <= 0 = pure ()
go x y =
let pLen = utf8LengthByLeader (A.unsafeIndex src x)
-- The next y is also the start of the current point in the output
yNext = y - pLen
-- Repeated unsafeWrite is faster than copyI
copyByte i = A.unsafeWrite dest (pOut' + i) (A.unsafeIndex src (pIn + i))
copyByte i = A.unsafeWrite dest (yNext + i) (A.unsafeIndex src (x + i))
in do
forM_ [0..pointLength - 1] copyByte
--A.copyI pointLength dest pOut' src pIn
go (pIn + pointLength) (pOut - pointLength)
forM_ [0..pLen - 1] copyByte
go (x + pLen) yNext
#else
reverse (Text (A.ByteArray ba) off len) = runST $ do
marr@(A.MutableByteArray mba) <- A.new len
Expand Down

0 comments on commit 6528755

Please sign in to comment.