on master help sign in
Optimise concat to not copy unless necessary

--HG-- extra : convert_revision : 2f94acc1cef5289703b4a768bf36d4692dd4c05a

commitcac81696a9d693fabc58029274c934b55cef8a76 authorBryan O'Sullivan <bos@serpentine.com> dateThu 26 Aug 2010, 18:27 (16 years ago) parent0bfcdf8
1 file changed+9−5
Data/Text.hs+9−5
Data/Text.hs+9−5
@@ -650,14 +650,18 @@ foldr1 f t = S.foldr1 f (stream t)
650650
651651-- | /O(n)/ Concatenate a list of 'Text's.
652652concat :: [Text] -> Text
653−concat ts = Text (A.run go) 0 len
653+concat ts = case ts' of
654+ [] -> empty
655+ [t] -> t
656+ _ -> Text (A.run go) 0 len
654657 where
655− len = L.sum (L.map (\(Text _ _ l) -> l) ts)
658+ ts' = L.filter (not . null) ts
659+ len = L.sum $ L.map lengthWord16 ts'
656660 go = do
657661 arr <- A.unsafeNew len
658− let step i (Text a o l) = let j = i + l in A.partialCopyI arr i a o j >> return j
659− foldM step 0 ts >> return arr
660−{-# INLINE concat #-}
662+ let step i (Text a o l) =
663+ let !j = i + l in A.partialCopyI arr i a o j >> return j
664+ foldM step 0 ts' >> return arr
661665
662666-- | /O(n)/ Map a function over a 'Text' that results in a 'Text', and
663667-- concatenate the results.