on master help sign in
Refactor text equality check
fe46b27Bryan O'Sullivan
Data/Text.hs+3−13
@@ -254,20 +254,10 @@ import Data.Int (Int64)
254-- Functions that can be fused by the compiler are marked with the
254-- Functions that can be fused by the compiler are marked with the
255-- phrase \"Subject to fusion\".
255-- phrase \"Subject to fusion\".
256
256
257−eq :: Text -> Text -> Bool
258−eq (Text arrA offA lenA) (Text arrB offB lenB)
259− | lenA /= lenB = False
260− | otherwise = go 0
261− where
262− go !n | n == lenA = True
263− | a /= b = False
264− | otherwise = go (n+1)
265− where a = A.unsafeIndex arrA (offA+n)
266− b = A.unsafeIndex arrB (offB+n)
267−{-# INLINE eq #-}
268−
269instance Eq Text where
257instance Eq Text where
270− (==) = eq
258+ Text arrA offA lenA == Text arrB offB lenB
259+ | lenA == lenB = A.equal arrA offA arrB offB lenA
260+ | otherwise = False
271 {-# INLINE (==) #-}
261 {-# INLINE (==) #-}
272
262
273instance Ord Text where
263instance Ord Text where
Data/Text/Array.hs+29
@@ -33,6 +33,7 @@ module Data.Text.Array
33 , copyM
33 , copyM
34 , copyI
34 , copyI
35 , empty
35 , empty
36+ , equal
36#if defined(ASSERTS)
37#if defined(ASSERTS)
37 , length
38 , length
38#endif
39#endif
@@ -265,3 +266,31 @@ copyI dest i0 src j0 top
265 | i >= top = return ()
266 | i >= top = return ()
266 | otherwise = do unsafeWrite dest i (src `unsafeIndex` j)
267 | otherwise = do unsafeWrite dest i (src `unsafeIndex` j)
267 slow (i+1) (j+1)
268 slow (i+1) (j+1)
269+
270+-- | Compare portions of two arrays for equality. No bounds checking
271+-- is performed.
272+equal :: Array -- ^ First
273+ -> Int -- ^ Offset into first
274+ -> Array -- ^ Second
275+ -> Int -- ^ Offset into second
276+ -> Int -- ^ Count
277+ -> Bool
278+equal arrA offA arrB offB count
279+ | wordAligned offA && wordAligned offB = fast 0
280+ | otherwise = slow 0
281+ where
282+ countWords = count `div` wordFactor
283+ fast !i
284+ | i >= countWords = slow (i * wordFactor)
285+ | a /= b = False
286+ | otherwise = fast (i+1)
287+ where a = unsafeIndexWord arrA (offAW+i)
288+ b = unsafeIndexWord arrB (offBW+i)
289+ offAW = offA `div` wordFactor
290+ offBW = offB `div` wordFactor
291+ slow !i
292+ | i >= count = True
293+ | a /= b = False
294+ | otherwise = slow (i+1)
295+ where a = unsafeIndex arrA (offA+i)
296+ b = unsafeIndex arrB (offB+i)