diff options
author | Andreas Klebinger <klebinger.andreas@gmx.at> | 2019-07-07 21:50:56 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-07-11 17:46:57 -0400 |
commit | 01ec8549871ebc43db3a7e28324222fa739c6531 (patch) | |
tree | 686b8395a2da9d12a9935fb7f204f7c19a70a5d0 | |
parent | cb5271ac9a6686d065de63d1dde80e713830e21b (diff) | |
download | haskell-01ec8549871ebc43db3a7e28324222fa739c6531.tar.gz |
Special case a few common patterns in unionLists.
In particular we very often pass one empty list and in these
cases we want to avoid the overhead of computing `xs ++ []`.
This should fix #14759 and #16911.
-rw-r--r-- | compiler/utils/ListSetOps.hs | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/compiler/utils/ListSetOps.hs b/compiler/utils/ListSetOps.hs index 8a6e07d84a..cad8cd9583 100644 --- a/compiler/utils/ListSetOps.hs +++ b/compiler/utils/ListSetOps.hs @@ -52,8 +52,17 @@ deleteBys eq xs ys = foldl' (flip (deleteBy eq)) xs ys -} +-- | Assumes that the arguments contain no duplicates unionLists :: (Outputable a, Eq a) => [a] -> [a] -> [a] --- Assumes that the arguments contain no duplicates +-- We special case some reasonable common patterns. +unionLists xs [] = xs +unionLists [] ys = ys +unionLists [x] ys + | isIn "unionLists" x ys = ys + | otherwise = x:ys +unionLists xs [y] + | isIn "unionLists" y xs = xs + | otherwise = y:xs unionLists xs ys = WARN(lengthExceeds xs 100 || lengthExceeds ys 100, ppr xs $$ ppr ys) [x | x <- xs, isn'tIn "unionLists" x ys] ++ ys |