on master help sign in
Lazy Text: reduce memory allocation during unstreaming
commitb6e6ac53a13cbbfab7b962e06ef372d86a08884b authorBryan O'Sullivan <bos@serpentine.com> dateWed 24 Oct 2012, 12:01 (14 years ago) parentdd7be63
1 file changed+10−5
Data/Text/Lazy/Fusion.hs+10−5
Data/Text/Lazy/Fusion.hs+10−5
@@ -24,6 +24,7 @@ module Data.Text.Lazy.Fusion
2424
2525import Prelude hiding (length)
2626import qualified Data.Text.Fusion.Common as S
27+import Control.Monad.ST (runST)
2728import Data.Text.Fusion.Internal
2829import Data.Text.Fusion.Size (isEmpty, unknownSize)
2930import Data.Text.Lazy.Internal
@@ -47,7 +48,7 @@ stream text = Stream next (text :*: 0) unknownSize
4748 where Iter c d = iter t i
4849{-# INLINE [0] stream #-}
4950
50−data UC s = UC s {-# UNPACK #-} !Int
51+data UC s = UC I.Text s
5152
5253-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using the given
5354-- chunk size.
@@ -60,13 +61,17 @@ unstreamChunks !chunkSize (Stream next s0 len0)
6061 case next s of
6162 Done -> Empty
6263 Skip s' -> outer s'
63− Yield x s' -> I.Text arr 0 len `chunk` outer s''
64− where (arr, UC s'' len) = A.run2 fill
64+ Yield x s' -> t `chunk` outer s''
65+ where UC t s'' = runST fill
6566 fill = do a <- A.new unknownLength
6667 unsafeWrite a 0 x >>= inner a unknownLength s'
6768 unknownLength = 4
69+ finish marr len s = do
70+ arr <- A.unsafeFreeze marr
71+ let !t = I.Text arr 0 len
72+ return (UC t s)
6873 inner marr !len s !i
69− | i + 1 >= chunkSize = return (marr, UC s i)
74+ | i + 1 >= chunkSize = finish marr i s
7075 | i + 1 >= len = {-# SCC "unstreamChunks/resize" #-} do
7176 let newLen = min (len `shiftL` 1) chunkSize
7277 marr' <- A.new newLen
@@ -75,7 +80,7 @@ unstreamChunks !chunkSize (Stream next s0 len0)
7580 | otherwise =
7681 {-# SCC "unstreamChunks/inner" #-}
7782 case next s of
78− Done -> return (marr, UC s i)
83+ Done -> finish marr i s
7984 Skip s' -> inner marr len s' i
8085 Yield x s' -> do d <- unsafeWrite marr i x
8186 inner marr len s' (i+d)