on master help sign in
Simplify and speed up lazy unstream
f7b8c88Bryan O'Sullivan
Data/Text/Fusion.hs+17−18
@@ -92,24 +92,23 @@ reverseStream (Text arr off len) = Stream next (off+len-1) (maxSize len)
92-- | /O(n)/ Convert a 'Stream Char' into a 'Text'.
92-- | /O(n)/ Convert a 'Stream Char' into a 'Text'.
93unstream :: Stream Char -> Text
93unstream :: Stream Char -> Text
94unstream (Stream next0 s0 len) = I.textP (P.fst a) 0 (P.snd a)
94unstream (Stream next0 s0 len) = I.textP (P.fst a) 0 (P.snd a)
95− where
95+ where
96− mlen = upperBound 4 len
97− a = A.run2 (A.unsafeNew mlen >>= (\arr -> outer arr mlen s0 0))
96+ a = A.run2 (A.unsafeNew mlen >>= \arr -> outer arr mlen s0 0)
97+ where mlen = upperBound 4 len
98− outer arr top = loop
98+ outer arr top = loop
99− where
99+ where
100+ loop !s !i =
101+ case next0 s of
102+ Done -> return (arr, i)
100− loop !s !i
103+ Skip s' -> loop s' i
104+ Yield x s'
101− | i + 1 >= top = {-# SCC "unstream/resize" #-}
105+ | j >= top -> {-# SCC "unstream/resize" #-} do
102− case next0 s of
103− Done -> return (arr, i)
104− Skip s' -> loop s' i
105− _ -> do
106− let top' = (top + 1) `shiftL` 1
106+ let top' = (top + 1) `shiftL` 1
107− arr' <- A.unsafeNew top'
107+ arr' <- A.unsafeNew top'
108− A.copy arr arr' >> outer arr' top' s i
108+ A.copy arr arr' >> outer arr' top' s i
109− | otherwise = case next0 s of
110− Done -> return (arr, i)
111− Skip s' -> loop s' i
112− Yield x s' -> unsafeWrite arr i x >>= loop s'
109+ | otherwise -> unsafeWrite arr i x >>= loop s'
110+ where j | ord x < 0x10000 = i
111+ | otherwise = i + 1
113{-# INLINE [0] unstream #-}
112{-# INLINE [0] unstream #-}
114{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
113{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
115
114