[commit: ghc] wip/T15449, wip/T16188, wip/llvm-configure-opts: Improve snocView implementation. (f4d8e90)
git at git.haskell.org
git at git.haskell.org
Sun Feb 10 21:31:12 UTC 2019
Repository : ssh://git@git.haskell.org/ghc
On branches: wip/T15449,wip/T16188,wip/llvm-configure-opts
Link : http://ghc.haskell.org/trac/ghc/changeset/f4d8e907b6b2e4110e1c6a21b34b1b46566ff6d5/ghc
>---------------------------------------------------------------
commit f4d8e907b6b2e4110e1c6a21b34b1b46566ff6d5
Author: klebinger.andreas at gmx.at <klebinger.andreas at gmx.at>
Date: Tue Jan 22 16:17:40 2019 +0100
Improve snocView implementation.
The new implementation isn't tailrecursive and instead
builds up the initial part of the list as it goes.
This improves allocation numbers as we don't build up an intermediate
list just to reverse it later.
This is slightly slower for lists of size <= 3. But in benchmarks
significantly faster for any list above 5 elements, assuming the
majority of the resulting list will be evaluated.
>---------------------------------------------------------------
f4d8e907b6b2e4110e1c6a21b34b1b46566ff6d5
compiler/utils/Util.hs | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/compiler/utils/Util.hs b/compiler/utils/Util.hs
index 876cd1e..16864fe 100644
--- a/compiler/utils/Util.hs
+++ b/compiler/utils/Util.hs
@@ -783,20 +783,25 @@ lastMaybe :: [a] -> Maybe a
lastMaybe [] = Nothing
lastMaybe xs = Just $ last xs
--- | If there is a good chance that you will only look at the last
--- element prefer seperate calls to @last@ + @init at .
--- @last@ does not allocate while traversing the list, while this
--- will. But if you are guaranteed to use both this will
--- usually be more efficient.
+-- | Split a list into its last element and the initial part of the list.
+-- @snocView xs = Just (init xs, last xs)@ for non-empty lists.
+-- @snocView xs = Nothing@ otherwise.
+-- Unless both parts of the result are guaranteed to be used
+-- prefer separate calls to @last@ + @init at .
+-- If you are guaranteed to use both, this will
+-- be more efficient.
snocView :: [a] -> Maybe ([a],a)
- -- Split off the last element
snocView [] = Nothing
-snocView xs = go [] xs
- where
- -- Invariant: second arg is non-empty
- go acc [x] = Just (reverse acc, x)
- go acc (x:xs) = go (x:acc) xs
- go _ [] = panic "Util: snocView"
+snocView xs
+ | (xs,x) <- go xs
+ = Just (xs,x)
+ where
+ go :: [a] -> ([a],a)
+ go [x] = ([],x)
+ go (x:xs)
+ | !(xs',x') <- go xs
+ = (x:xs', x')
+ go [] = error "impossible"
split :: Char -> String -> [String]
split c s = case rest of
More information about the ghc-commits
mailing list