[GHC] #15131: Speed up certain Foldable NonEmpty methods
GHC
ghc-devs at haskell.org
Wed May 9 10:41:11 UTC 2018
#15131: Speed up certain Foldable NonEmpty methods
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: (none)
Type: bug | Status: patch
Priority: normal | Milestone: 8.6.1
Component: Core Libraries | Version: 8.2.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Runtime | Unknown/Multiple
performance bug | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D4677
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by YitzGale):
I just gave one or two examples in the reddit thread, but really all the
methods need review.
I'm not convinced about the default {{length}} being better. Perhaps
switch the order, {{List.length as + 1}}. Does GHC not inline primitive
{{+}}? And you do an extra {{+0}}. But if I'm wrong, the clear explanatory
comment is highly appreciated.
Why not just put the obvious trivial explicit implementation for every
method? It would make the code cleaner and easier to read, without having
to look up the default and then scratch your head about what gets
optimized.
Note that for historical reasons several methods for List are still
implemented via {{foldl}}. That is in very rare cases better than
{{foldl'}}, in many cases the same because GHC optimizes it, and in some
cases worse. My opinion is that {{NonEmpty}} should always behave the same
as {{List}}, whatever that may be. It's worth it to add one extra
operation to the {{NonEmpty}} implementation so that we can refer to the
List implementation and not hard-code a copy of it.
Here's my alternative "patch" (sorry I don't know how to offer an
alternative patch on Phab):
{{{
#!haskell
instance Foldable NonEmpty where
elem x (a :| as) = x == a || x `List.elem` as
foldl f z ~(a :| as) = List.foldl f (f z a) as
foldl' f z ~(a :| as) = let z' = f z a in z' `seq` foldl' f z' as
foldl1 f ~(a :| as) = List.foldl f a as
foldr f z ~(a :| as) = f a (List.foldr f z as)
foldr1 f ~(a :| as) = List.foldr f a as
foldMap f ~(a :| as) = f a `mappend` foldMap f as
fold ~(m :| ms) = m `mappend` fold ms
length (_ :| as) = List.length as + 1
maximum (a :| as) = max a (List.maximum as)
minimum (a :| as) = min a (List.minimum as)
null _ = False
product (a :| as) = a * List.product as
sum (a :| as) = a + List.sum as
toList (a :| as) = a : as
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15131#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list