on master help sign in
Improve copy performance

--HG-- extra : convert_revision : c58b93eb9fb843f818a83bd20edce6fa31f7c0d6

commit2943602c1adcd642431885b7ad5cd86217493cea authorBryan O'Sullivan <bos@serpentine.com> dateSun 15 Aug 2010, 05:47 (16 years ago) parent8028b36
1 file changed+32−10
Data/Text/Array.hs+32−10
Data/Text/Array.hs+32−10
@@ -56,13 +56,13 @@ if (_k_) < 0 || (_k_) >= (_len_) then error ("Data.Text.Array." ++ (_func_) ++ "
5656#if defined(ASSERTS)
5757import Control.Exception (assert)
5858#endif
59−import Data.Text.UnsafeShift (shiftL)
59+import Data.Text.UnsafeShift (shiftL, shiftR)
6060import GHC.Base (ByteArray#, MutableByteArray#, Int(..),
6161 indexWord16Array#, newByteArray#,
62− readWord16Array#, unsafeCoerce#,
63− writeWord16Array#)
62+ readWord16Array#, readWordArray#, unsafeCoerce#,
63+ writeWord16Array#, writeWordArray#)
6464import GHC.ST (ST(..), runST)
65−import GHC.Word (Word16(..))
65+import GHC.Word (Word16(..), Word(..))
6666import Prelude hiding (length, read)
6767
6868-- | Immutable array type.
@@ -143,6 +143,24 @@ unsafeWrite (MArray len marr#) i@(I# i#) (W16# e#) = ST $ \s1# ->
143143 s2# -> (# s2#, () #)
144144{-# INLINE unsafeWrite #-}
145145
146+-- | Unchecked read of a mutable array. May return garbage or
147+-- crash on an out-of-bounds access.
148+unsafeReadWord :: MArray s -> Int -> ST s Word
149+unsafeReadWord (MArray len mba#) i@(I# i#) = ST $ \s# ->
150+ CHECK_BOUNDS("unsafeRead64",len,i)
151+ case readWordArray# mba# i# s# of
152+ (# s2#, r# #) -> (# s2#, W# r# #)
153+{-# INLINE unsafeReadWord #-}
154+
155+-- | Unchecked write of a mutable array. May return garbage or crash
156+-- on an out-of-bounds access.
157+unsafeWriteWord :: MArray s -> Int -> Word -> ST s ()
158+unsafeWriteWord (MArray len marr#) i@(I# i#) (W# e#) = ST $ \s1# ->
159+ CHECK_BOUNDS("unsafeWriteWord",len,i)
160+ case writeWordArray# marr# i# e# s1# of
161+ s2# -> (# s2#, () #)
162+{-# INLINE unsafeWriteWord #-}
163+
146164-- | Convert an immutable array to a list.
147165toList :: Array -> [Word16]
148166toList a = loop 0
@@ -172,13 +190,17 @@ run2 k = runST (do
172190copy :: MArray s -- ^ source array
173191 -> MArray s -- ^ destination array
174192 -> ST s ()
175−copy src dest
176− | length dest >= length src = copy_loop 0
177− | otherwise = fail "Data.Text.Array.copy: array too small"
193+copy src@(MArray slen _) dest@(MArray dlen _)
194+ | dlen >= slen = fast_loop 0
195+ | otherwise = fail "Data.Text.Array.copy: array too small"
178196 where
179− len = length src
180− copy_loop i
181− | i >= len = return ()
197+ nwds = slen `div` (SIZEOF_HSWORD `shiftR` 1)
198+ fast_loop !i
199+ | i >= nwds = copy_loop (i * (SIZEOF_HSWORD `shiftR` 1))
200+ | otherwise = do unsafeReadWord src i >>= unsafeWriteWord dest i
201+ fast_loop (i+1)
202+ copy_loop !i
203+ | i >= slen = return ()
182204 | otherwise = do unsafeRead src i >>= unsafeWrite dest i
183205 copy_loop (i+1)
184206{-# INLINE copy #-}