[GHC] #15176: Superclass `Monad m =>` makes program run 100 times slower

GHC ghc-devs at haskell.org
Tue May 22 16:17:57 UTC 2018


#15176: Superclass `Monad m =>` makes program run 100 times slower
-------------------------------------+-------------------------------------
        Reporter:  danilo2           |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  highest           |            Milestone:  8.6.1
       Component:  Compiler          |              Version:  8.4.2
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  performance bug                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 I agree that predictable performance is super-important.  So we give a
 high priority to unexpected performance lossage.

 I'd love to know what is going on in your application, but I wonder if you
 or someone else can help characterise what is going on, and perhaps distil
 into a smaller test case?

 What I can say is that the difference between your two classes is the
 difference between
 {{{
 newtype LayersFoldableBuilder__ t (layers :: [Type]) m
   = MkD (SomePtr -> m (Fold.Result t) -> m (Fold.Result t))
 }}}
 and
 {{{
 data LayersFoldableBuilder__ t (layers :: [Type]) m
   = MkD (Monad m)
         (SomePtr -> m (Fold.Result t) -> m (Fold.Result t))
 }}}
 That is, without the superclass a `LayersFoldableBuilder__` dictionary is
 represented just by the `buildLayersFold__` function itself; when you add
 the superclass, it turns into a heap-allocated pair of that function and a
 `Monad m` dictionary.

 This might change perf slightly, but a factor of 100 is ridiculous.  I
 have literally no idea why that is happening.

 The change is so egregious that profiling ought to lead you right to it.
 (Or use `-ticky` which is faster and less invasive.)

 You are using 8.4, right?  Does it happen with 8.2?  (Or is that hard to
 find out?)

 Also does it also happen if, instead of adding `Monad m =>` you add a
 dummy method to the class, like this
 {{{
 class LayersFoldableBuilder__ t (layers :: [Type]) m where
     buildLayersFold__ :: SomePtr -> m (Fold.Result t) -> m (Fold.Result t)
     dummy :: t -> t
 }}}

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


More information about the ghc-tickets mailing list