Commits

Bryan O'Sullivan  committed 51c1178

A small improvement in Text generation efficiency.

The specialised Run tuple avoids boxing and indirection for both
the MArray and Int parameters in the predecessor code.

I think I can do better, though.

  • Participants
  • Parent commits 7082e94

Comments (0)

Files changed (2)

File Data/Text/Fusion.hs

                 fromIntegral, otherwise)
 import Data.Bits ((.&.))
 import Data.Text.Internal (Text(..))
+import Data.Text.Private (Run(..), runText)
 import Data.Text.UnsafeChar (ord, unsafeChr, unsafeWrite)
 import Data.Text.UnsafeShift (shiftL, shiftR)
 import qualified Data.Text.Array as A
 
 -- | /O(n)/ Convert a 'Stream Char' into a 'Text'.
 unstream :: Stream Char -> Text
-unstream (Stream next0 s0 len) = I.textP (P.fst a) 0 (P.snd a)
+unstream (Stream next0 s0 len) = a
   where
-    a = A.run2 (A.new mlen >>= \arr -> outer arr mlen s0 0)
+    a = runText (A.new mlen >>= \arr -> outer arr mlen s0 0)
       where mlen = upperBound 4 len
     outer arr top = loop
       where
         loop !s !i =
             case next0 s of
-              Done          -> return (arr, i)
+              Done          -> return (Run arr i)
               Skip s'       -> loop s' i
               Yield x s'
                 | j >= top  -> {-# SCC "unstream/resize" #-} do

File Data/Text/Private.hs

-{-# LANGUAGE BangPatterns, UnboxedTuples #-}
+{-# LANGUAGE BangPatterns, Rank2Types, UnboxedTuples #-}
 
 -- |
 -- Module      : Data.Text.Private
 
 module Data.Text.Private
     (
-      span_
+      Run(..)
+    , runText
+    , span_
     ) where
 
+import Control.Monad.ST (ST, runST)
 import Data.Text.Internal (Text(..), textP)
 import Data.Text.Unsafe (Iter(..), iter)
+import qualified Data.Text.Array as A
 
 span_ :: (Char -> Bool) -> Text -> (# Text, Text #)
 span_ p t@(Text arr off len) = (# hd,tl #)
                 | otherwise      = i
             where Iter c d       = iter t i
 {-# INLINE span_ #-}
+
+data Run s = Run !(A.MArray s) !Int
+
+runText :: (forall s. ST s (Run s)) -> Text
+runText act = runST (do Run marr len <- act
+                        arr <- A.unsafeFreeze marr
+                        return (textP arr 0 len))
+{-# INLINE runText #-}