[GHC] #9630: compile-time performance regression (probably due to Generics)

GHC ghc-devs at haskell.org
Fri Jun 2 18:08:11 UTC 2017


#9630: compile-time performance regression (probably due to Generics)
-------------------------------------+-------------------------------------
        Reporter:  hvr               |                Owner:  dfeuer
            Type:  bug               |               Status:  new
        Priority:  high              |            Milestone:  8.2.1
       Component:  Compiler          |              Version:  7.9
      Resolution:                    |             Keywords:  deriving-
                                     |  perf, Generics
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  performance bug                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #9583, #10293,    |  Differential Rev(s):
  #13059, #10818                     |
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by dfeuer):

 I pored over `-ddump-ds`, and I think I see what's going on. Suppose we
 have (cereal-style, but without any `INLINE`s)

 {{{#!hs
 class Serialize t where
     put :: Putter t
     get :: Get t

     default put :: (Generic t, GSerialize (Rep t)) => Putter t
     put = gPut . from

     default get :: (Generic t, GSerialize (Rep t)) => Get t
     get = to <$> gGet


 data T = T
  () () () () ()
   deriving Generic
 instance Serialize T
 }}}

 What we want to do is build a single `GSerialize (Rep T)` dictionary and
 share it between `put` and `get`. But when we desugar `instance Serialize
 T`, we end up building a `GSerialize (Rep T)` dictionary in the definition
 of `put` and ''another one'' in the definition of `get`.

 The problem even occurs without `DefaultSignatures`; writing the instance
 by hand using `gPut` and `gGet` is sufficient to demonstrate the problem:

 {{{#!hs
 instance Serialize T where
   put = gPut . from
   get = to <$> gGet
 }}}

 bgamari indicates that instances are supposed to be cached. Indeed, if I
 write

 {{{#!hs
 putT :: Putter T
 putT = gPut . from

 getT :: Get T
 getT = to <$> gGet
 }}}

 at the top level, then all is well.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9630#comment:55>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list