Bryan O'Sullivan avatar Bryan O'Sullivan committed b4a194d

Lazy Text: reduce memory allocation during unstreaming

Comments (0)

Files changed (1)

Data/Text/Lazy/Fusion.hs

 
 import Prelude hiding (length)
 import qualified Data.Text.Fusion.Common as S
+import Control.Monad.ST (runST)
 import Data.Text.Fusion.Internal
 import Data.Text.Fusion.Size (isEmpty, unknownSize)
 import Data.Text.Lazy.Internal
         where Iter c d = iter t i
 {-# INLINE [0] stream #-}
 
-data UC s = UC s {-# UNPACK #-} !Int
+data UC s = UC I.Text s
 
 -- | /O(n)/ Convert a 'Stream Char' into a 'Text', using the given
 -- chunk size.
               case next s of
                 Done       -> Empty
                 Skip s'    -> outer s'
-                Yield x s' -> I.Text arr 0 len `chunk` outer s''
-                  where (arr, UC s'' len) = A.run2 fill
+                Yield x s' -> t `chunk` outer s''
+                  where UC t s'' = runST fill
                         fill = do a <- A.new unknownLength
                                   unsafeWrite a 0 x >>= inner a unknownLength s'
                         unknownLength = 4
+    finish marr len s = do
+      arr <- A.unsafeFreeze marr
+      let !t = I.Text arr 0 len
+      return (UC t s)
     inner marr !len s !i
-        | i + 1 >= chunkSize = return (marr, UC s i)
+        | i + 1 >= chunkSize = finish marr i s
         | i + 1 >= len       = {-# SCC "unstreamChunks/resize" #-} do
             let newLen = min (len `shiftL` 1) chunkSize
             marr' <- A.new newLen
         | otherwise =
             {-# SCC "unstreamChunks/inner" #-}
             case next s of
-              Done        -> return (marr, UC s i)
+              Done        -> finish marr i s
               Skip s'     -> inner marr len s' i
               Yield x s'  -> do d <- unsafeWrite marr i x
                                 inner marr len s' (i+d)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.