Commits

Bryan O'Sullivan committed 63713af

Refactor text equality check

Comments (0)

Files changed (2)

 -- Functions that can be fused by the compiler are marked with the
 -- phrase \"Subject to fusion\".
 
-eq :: Text -> Text -> Bool
-eq (Text arrA offA lenA) (Text arrB offB lenB)
-   | lenA /= lenB = False
-   | otherwise    = go 0
- where
-   go !n | n == lenA = True
-         | a /= b    = False
-         | otherwise = go (n+1)
-         where a = A.unsafeIndex arrA (offA+n)
-               b = A.unsafeIndex arrB (offB+n)
-{-# INLINE eq #-}
-
 instance Eq Text where
-    (==) = eq
+    Text arrA offA lenA == Text arrB offB lenB
+        | lenA == lenB = A.equal arrA offA arrB offB lenA
+        | otherwise    = False
     {-# INLINE (==) #-}
 
 instance Ord Text where

Data/Text/Array.hs

     , copyM
     , copyI
     , empty
+    , equal
 #if defined(ASSERTS)
     , length
 #endif
         | i >= top  = return ()
         | otherwise = do unsafeWrite dest i (src `unsafeIndex` j)
                          slow (i+1) (j+1)
+
+-- | Compare portions of two arrays for equality.  No bounds checking
+-- is performed.
+equal :: Array                  -- ^ First
+      -> Int                    -- ^ Offset into first
+      -> Array                  -- ^ Second
+      -> Int                    -- ^ Offset into second
+      -> Int                    -- ^ Count
+      -> Bool
+equal arrA offA arrB offB count
+    | wordAligned offA && wordAligned offB = fast 0
+    | otherwise                            = slow 0
+  where
+    countWords = count `div` wordFactor
+    fast !i
+        | i >= countWords = slow (i * wordFactor)
+        | a /= b          = False
+        | otherwise       = fast (i+1)
+        where a     = unsafeIndexWord arrA (offAW+i)
+              b     = unsafeIndexWord arrB (offBW+i)
+              offAW = offA `div` wordFactor
+              offBW = offB `div` wordFactor
+    slow !i
+        | i >= count = True
+        | a /= b     = False
+        | otherwise  = slow (i+1)
+        where a = unsafeIndex arrA (offA+i)
+              b = unsafeIndex arrB (offB+i)