[GHC] #11735: Optimize coercionKind

GHC ghc-devs at haskell.org
Mon Jan 29 16:24:02 UTC 2018


#11735: Optimize coercionKind
-------------------------------------+-------------------------------------
        Reporter:  goldfire          |                Owner:  (none)
            Type:  task              |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  7.10.3
      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 goldfire):

 Replying to [comment:45 tdammers]:
 > Looking at HEAD on `master`, we have the `coercionKindRole` function
 that is simply recursive for NthCo, and has the `nth` call embedded. So
 for nested NthCo's, its behavior should be quadratic.

 I disagree here. I think the old `coercionKindRole` was not quadratic in
 this way (ignoring the `ForAllCo` change). Every `coercionKindRole`
 recurrence calls `getNth` (twice), but that doesn't lead to quadratic
 behavior in the depth of `NthCo` nesting, which is what we're worried
 about. It does mean that running time will be proportional to the sum of
 the indices in the `NthCo`s, but that's to be expected. Let's put this
 another way: pretend all the indices in the `NthCo`s are 1, a constant.
 (This is fairly close to reality, anyway.) Then, we're linear, not
 quadratic.

 >
 > The un-refactored version has `coercionKind`, which is simply recursive
 (O(n)), and we have `coercionRole`, which recurses via `coercionKindRole`.
 The latter is really just a matter of calling `coercionKind` and
 `coercionRole` individually though; the `coercionRole` call makes
 `coercionRole` simply recursive (O(n)), but the `coercionKind` call
 introduces another O(n), making the entire thing also quadratic.

 Agreed here. But note that this would remain quadratic even if all the
 indices in the `NthCo`s were 1. So, if you call the original
 `coercionKindRole` quadratic, then this would be ''cubic'' (but I don't
 think that's a fair characterization -- there's nothing raised to the
 third power here).

 >
 > So in terms of big-O, HEAD and "un-refactored" should be the same. Why
 one perfoms better than the other is somewhat unclear to me though.

 Disagree here, as explained above. The old `coercionKindRole` was
 asymptotically better. But now that we cache roles, it should be good
 again.

 > > On the other hand, the separated version really is quadratic... and
 yet it's faster (on this test case)! That's the conundrum.
 >
 > Yes, but we don't know if it's actually big-O-faster, or just happens
 have a more favorable constant factor.

 Fair enough.

 I'm stymied as to why my patches make things worse. Maybe moving the
 `isReflexiveCo` check in `addCoerce` to the top was a bad idea? Try moving
 that back to where it was and then try again. The `simplCast` stuff should
 be vastly better than it was!

 Thanks!

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


More information about the ghc-tickets mailing list