on master help sign in
Optimise concat to not copy unless necessary
cac8169Bryan O'Sullivan
Data/Text.hs+9−5
@@ -650,14 +650,18 @@ foldr1 f t = S.foldr1 f (stream t)
650
650
651-- | /O(n)/ Concatenate a list of 'Text's.
651-- | /O(n)/ Concatenate a list of 'Text's.
652concat :: [Text] -> Text
652concat :: [Text] -> Text
653+concat ts = case ts' of
654+ [] -> empty
655+ [t] -> t
653−concat ts = Text (A.run go) 0 len
656+ _ -> Text (A.run go) 0 len
654 where
657 where
658+ ts' = L.filter (not . null) ts
655− len = L.sum (L.map (\(Text _ _ l) -> l) ts)
659+ len = L.sum $ L.map lengthWord16 ts'
656 go = do
660 go = do
657 arr <- A.unsafeNew len
661 arr <- A.unsafeNew len
662+ let step i (Text a o l) =
658− let step i (Text a o l) = let j = i + l in A.partialCopyI arr i a o j >> return j
663+ let !j = i + l in A.partialCopyI arr i a o j >> return j
659− foldM step 0 ts >> return arr
664+ foldM step 0 ts' >> return arr
660−{-# INLINE concat #-}
661
665
662-- | /O(n)/ Map a function over a 'Text' that results in a 'Text', and
666-- | /O(n)/ Map a function over a 'Text' that results in a 'Text', and
663-- concatenate the results.
667-- concatenate the results.