
#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