Commit 77398b67 authored by Sylvain Henry's avatar Sylvain Henry Committed by Marge Bot
Browse files

Avoid allocations in `splitAtList` (#18535)

As suspected by @simonpj in #18535, avoiding allocations in
`GHC.Utils.Misc.splitAtList` when there are no leftover arguments is
beneficial for performance:

   On CI validate-x86_64-linux-deb9-hadrian:
    T12227 -7%
    T12545 -12.3%
    T5030  -10%
    T9872a -2%
    T9872b -2.1%
    T9872c -2.5%

Metric Decrease:
    T12227
    T12545
    T5030
    T9872a
    T9872b
    T9872c
parent c8873b52
Pipeline #23196 failed with stages
in 317 minutes and 41 seconds
......@@ -774,12 +774,15 @@ dropList _ xs@[] = xs
dropList (_:xs) (_:ys) = dropList xs ys
-- | Given two lists xs=x0..xn and ys=y0..ym, return `splitAt n ys`.
splitAtList :: [b] -> [a] -> ([a], [a])
splitAtList [] xs = ([], xs)
splitAtList _ xs@[] = (xs, xs)
splitAtList (_:xs) (y:ys) = (y:ys', ys'')
where
(ys', ys'') = splitAtList xs ys
splitAtList xs ys = go 0 xs ys
where
-- we are careful to avoid allocating when there are no leftover
-- arguments: in this case we can return "ys" directly (cf #18535)
go _ _ [] = (ys, []) -- len(ys) <= len(xs)
go n [] bs = (take n ys, bs) -- = splitAt n ys
go n (_:as) (_:bs) = go (n+1) as bs
-- drop from the end of a list
dropTail :: Int -> [a] -> [a]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment