Changes between Initial Version and Version 1 of NestedCPR/better-ho-cardinality


Ignore:
Timestamp:
Jan 7, 2014 10:19:21 AM (6 years ago)
Author:
nomeata
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • NestedCPR/better-ho-cardinality

    v1 v1  
     1
     2== better-ho-cardinality ==
     3
     4It would be nice to merge the code structure improvements and notes into master, to keep my branch short. But it is based on `better-ho-cardinality`, and that is not suitable for merging because of unexpected regressions even in `nofib` and `rtak`. So I am investigating.
     5
     6In these tests, it is related to reading and showing data. Small example:
     7{{{
     8#!haskell
     9main = (read "10" :: Int) `seq` return ()
     10}}}
     11Baseline: 49832, `better-ho-cardinality`: 49968. Unfortunately, the changes to, for example, `GHC.Read` are not small, and probably mostly benign...
     12
     13Trying to minimize and isolate the problem. After some aggressive code deleting, this is where I ended up:
     14{{{
     15#!haskell
     16{-# LANGUAGE RankNTypes #-}
     17
     18data P a
     19  = Get (Char -> P a)
     20  | Result a
     21
     22Get f1     `mplus` Get f2     = undefined
     23Result x   `mplus` _          = Result x
     24
     25newtype ReadP a = R (forall b . (a -> P b) -> P b)
     26
     27instance Monad ReadP where
     28  return x  = R (\k -> k x)
     29  R m >>= f = R (\k -> m (\a -> let R m' = f a in m' k))
     30
     31readP_to_S (R f) = f Result `seq` ()
     32
     33ppp :: ReadP a -> ReadP a -> ReadP a
     34ppp (R f1) (R f2) = R (\k -> f1 k `mplus` f2 k)
     35
     36paren :: ReadP () -> ReadP ()
     37paren p = p >> return ()
     38
     39parens :: ReadP () -> ReadP ()
     40parens p = optional
     41 where
     42  optional  = ppp p mandatory
     43  mandatory = paren optional
     44
     45foo = paren ( return () )
     46
     47foo2 = ppp (parens ( return () )) (parens (return ()))
     48
     49main = readP_to_S foo `seq` readP_to_S foo2 `seq` return ()
     50}}}
     51it is important that both `paren` and `parens` are used more than once; if there is only one use-site, the problem disappears (which made it hard to find). Also, most other changes prevent the increase in allocations: Removing the `Monad` instance and turning its methods into regular functions; adding `NOINLINE` annotations to `paren` or `parens`; changing `foo2` to `ppp foo foo`; even removing the dead code that is the first line of the `mplus` function.
     52
     53Further investigation and aggresive patch-splitting shows that the arity change is causing the regression. Pushed everything but that patch to master, that patch now lives in `wip/exprArity`.