Skip to content

Commit 635560f

Browse files
clyringhs-viktor
authored andcommitted
Prevent Lazy.uncons from allocating a thunk (haskell#559)
...at least for the second component of its result. The thunk for the first component is a bit hairier because the readWord8OffAddr# is considered a side effect by GHC and hence can currently never go away unless it is used lazily. See also haskell#558.
1 parent 583f938 commit 635560f

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

Data/ByteString/Lazy.hs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,9 +353,13 @@ head (Chunk c _) = S.unsafeHead c
353353
-- if it is empty.
354354
uncons :: ByteString -> Maybe (Word8, ByteString)
355355
uncons Empty = Nothing
356-
uncons (Chunk c cs)
357-
= Just (S.unsafeHead c,
358-
if S.length c == 1 then cs else Chunk (S.unsafeTail c) cs)
356+
uncons (Chunk c cs) = case S.length c of
357+
-- Don't move this test inside of the Just or (,).
358+
-- We don't want to allocate a thunk to put inside of the tuple!
359+
-- And if "let !tl = ... in Just (..., tl)" seems more appealing,
360+
-- remember that this function must remain lazy in cs.
361+
1 -> Just (S.unsafeHead c, cs)
362+
_ -> Just (S.unsafeHead c, Chunk (S.unsafeTail c) cs)
359363
{-# INLINE uncons #-}
360364

361365
-- | /O(1)/ Extract the elements after the head of a ByteString, which must be

0 commit comments

Comments
 (0)