on master help sign in
Speed up lazy text equality
8dec5e3Bryan O'Sullivan
Data/Text/Lazy.hs+15−1
@@ -204,8 +204,22 @@ import Data.Text.Internal (textP)
204import qualified Data.Text.Util as U
204import qualified Data.Text.Util as U
205import Data.Text.Lazy.Search (indices)
205import Data.Text.Lazy.Search (indices)
206
206
207+equal :: Text -> Text -> Bool
208+equal Empty Empty = True
209+equal Empty _ = False
210+equal _ Empty = False
211+equal (Chunk a as) (Chunk b bs) =
212+ case compare lenA lenB of
213+ LT -> a == (T.takeWord16 lenA b) &&
214+ as `equal` Chunk (T.dropWord16 lenA b) bs
215+ EQ -> a == b && as `equal` bs
216+ GT -> T.takeWord16 lenB a == b &&
217+ Chunk (T.dropWord16 lenB a) as `equal` bs
218+ where lenA = T.lengthWord16 a
219+ lenB = T.lengthWord16 b
220+
207instance Eq Text where
221instance Eq Text where
208− t1 == t2 = stream t1 == stream t2
222+ (==) = equal
209 {-# INLINE (==) #-}
223 {-# INLINE (==) #-}
210
224
211instance Ord Text where
225instance Ord Text where
Data/Text/Unsafe.hs+12
@@ -21,6 +21,8 @@ module Data.Text.Unsafe
21 , unsafeHead
21 , unsafeHead
22 , unsafeTail
22 , unsafeTail
23 , lengthWord16
23 , lengthWord16
24+ , takeWord16
25+ , dropWord16
24 ) where
26 ) where
25
27
26#if defined(ASSERTS)
28#if defined(ASSERTS)
@@ -132,3 +134,13 @@ inlineInterleaveST (ST m) = ST $ \ s ->
132lengthWord16 :: Text -> Int
134lengthWord16 :: Text -> Int
133lengthWord16 (Text _arr _off len) = len
135lengthWord16 (Text _arr _off len) = len
134{-# INLINE lengthWord16 #-}
136{-# INLINE lengthWord16 #-}
137+
138+-- | /O(1)/ Unchecked take of 'k' 'Word16's from the front of a 'Text'.
139+takeWord16 :: Int -> Text -> Text
140+takeWord16 k (Text arr off _len) = Text arr off k
141+{-# INLINE takeWord16 #-}
142+
143+-- | /O(1)/ Unchecked drop of 'k' 'Word16's from the front of a 'Text'.
144+dropWord16 :: Int -> Text -> Text
145+dropWord16 k (Text arr off len) = Text arr (off+k) (len-k)
146+{-# INLINE dropWord16 #-}