on master help sign in
Speed up the Ord instance for Text
commit776b5e94e0a38fb3f4fbae30f60de70ed049e3b9 authorBryan O'Sullivan <bos@serpentine.com> dateTue 19 Oct 2010, 21:37 (16 years ago) parent9090c9d
2 files changed+53−2
Data/Text.hs+15−2 tests/benchmarks/Ordering.hs+38
Data/Text.hs+15−2
@@ -261,8 +261,7 @@ instance Eq Text where
261261 {-# INLINE (==) #-}
262262
263263instance Ord Text where
264− compare t1 t2 = compare (stream t1) (stream t2)
265− {-# INLINE compare #-}
264+ compare = compareText
266265
267266instance Show Text where
268267 showsPrec p ps r = showsPrec p (unpack ps) r
@@ -304,6 +303,20 @@ instance Data Text where
304303 dataTypeOf _ = mkNorepType "Data.Text.Text"
305304#endif
306305
306+-- | /O(n)/ Compare two 'Text' values lexicographically.
307+compareText :: Text -> Text -> Ordering
308+compareText ta@(Text _arrA _offA lenA) tb@(Text _arrB _offB lenB)
309+ | lenA == 0 && lenB == 0 = EQ
310+ | otherwise = go 0 0
311+ where
312+ go !i !j
313+ | i >= lenA || j >= lenB = compare lenA lenB
314+ | a < b = LT
315+ | a > b = GT
316+ | otherwise = go (i+di) (j+dj)
317+ where Iter a di = iter ta i
318+ Iter b dj = iter tb j
319+
307320-- -----------------------------------------------------------------------------
308321-- * Conversion to/from 'Text'
309322
tests/benchmarks/Ordering.hsnew file+38
@@ -0,0 +1,38 @@
1+import System.Environment
2+import qualified Data.ByteString.Char8 as B
3+import qualified Data.ByteString.Lazy.Char8 as BL
4+import qualified Data.Text as T
5+import qualified Data.Text.Encoding as T
6+import qualified Data.Text.Lazy as TL
7+import qualified Data.Text.Lazy.Encoding as TL
8+
9+every :: Int -> [a] -> [a]
10+every k = go k
11+ where go n (x:xs)
12+ | n < k = go (n+1) xs
13+ | otherwise = x : go 1 xs
14+ go _ _ = []
15+
16+func :: (Ord a) => [a] -> IO ()
17+func ls = print . sum . map f $ every 1000 ls
18+ where f needle = length . filter ((==GT) . compare needle) $ ls
19+
20+bytestring haystack = func =<< B.lines `fmap` B.readFile haystack
21+
22+lazyBytestring haystack = func =<< BL.lines `fmap` BL.readFile haystack
23+
24+text haystack = func =<< (T.lines . T.decodeUtf8) `fmap` B.readFile haystack
25+
26+lazyText haystack = func =<<
27+ (TL.lines . TL.decodeUtf8) `fmap` BL.readFile haystack
28+
29+string haystack = func =<< lines `fmap` readFile haystack
30+
31+main = do
32+ args <- getArgs
33+ case args of
34+ ["bs",h] -> bytestring h
35+ ["lazybs",h] -> lazyBytestring h
36+ ["text",h] -> text h
37+ ["lazytext",h] -> lazyText h
38+ ["string",h] -> string h