on master help sign in
Ensure that GHC's CPR optimization fires.
5637164Bryan O'Sullivan
Data/Text/Search.hs+4−2
@@ -39,6 +39,8 @@ import Data.Text.Fusion.Internal (PairS(..))
39import Data.Bits ((.|.), (.&.))
39import Data.Bits ((.|.), (.&.))
40import Data.Text.UnsafeShift (shiftL)
40import Data.Text.UnsafeShift (shiftL)
41
41
42+data T = {-# UNPACK #-} !Word64 :* {-# UNPACK #-} !Int
43+
42-- | /O(n+m)/ Find the offsets of all non-overlapping indices of
44-- | /O(n+m)/ Find the offsets of all non-overlapping indices of
43-- @needle@ within @haystack@. The offsets returned represent
45-- @needle@ within @haystack@. The offsets returned represent
44-- locations in the low-level array.
46-- locations in the low-level array.
@@ -60,9 +62,8 @@ indices _needle@(Text narr noff nlen) _haystack@(Text harr hoff hlen)
60 hindex k = A.unsafeIndex harr (hoff+k)
62 hindex k = A.unsafeIndex harr (hoff+k)
61 hindex' k | k == hlen = 0
63 hindex' k | k == hlen = 0
62 | otherwise = A.unsafeIndex harr (hoff+k)
64 | otherwise = A.unsafeIndex harr (hoff+k)
63− (mask :: Word64) :*: skip = buildTable 0 0 (nlen-2)
64 buildTable !i !msk !skp
65 buildTable !i !msk !skp
65− | i >= nlast = (msk .|. swizzle z) :*: skp
66+ | i >= nlast = (msk .|. swizzle z) :* skp
66 | otherwise = buildTable (i+1) (msk .|. swizzle c) skp'
67 | otherwise = buildTable (i+1) (msk .|. swizzle c) skp'
67 where c = nindex i
68 where c = nindex i
68 skp' | c == z = nlen - i - 2
69 skp' | c == z = nlen - i - 2
@@ -81,6 +82,7 @@ indices _needle@(Text narr noff nlen) _haystack@(Text harr hoff hlen)
81 | c == z = skip + 1
82 | c == z = skip + 1
82 | otherwise = 1
83 | otherwise = 1
83 nextInPattern = mask .&. swizzle (hindex' (i+nlen)) == 0
84 nextInPattern = mask .&. swizzle (hindex' (i+nlen)) == 0
85+ !(mask :* skip) = buildTable 0 0 (nlen-2)
84 scanOne c = loop 0
86 scanOne c = loop 0
85 where loop !i | i >= hlen = []
87 where loop !i | i >= hlen = []
86 | hindex i == c = i : loop (i+1)
88 | hindex i == c = i : loop (i+1)