[GHC] #8147: Exponential behavior in instance resolution on fixpoint-of-sum
GHC
ghc-devs at haskell.org
Wed Aug 21 03:47:57 CEST 2013
#8147: Exponential behavior in instance resolution on fixpoint-of-sum
-------------------------+-------------------------------------------------
Reporter: | Owner:
jkoppel | Status: new
Type: bug | Milestone:
Priority: | Version: 7.6.3
normal | Operating System: Unknown/Multiple
Component: | Type of failure: Compile-time performance bug
Compiler | Test Case:
Keywords: | Blocking:
performance, |
Architecture: |
Unknown/Multiple |
Difficulty: |
Unknown |
Blocked By: |
Related Tickets: |
-------------------------+-------------------------------------------------
Doing instance resolution on a fixpoint-of-sum type takes a very long
time. This is possibly the same issue as issue #5642.
These are the numbers I see for various n:
{{{
10 : 0.329s
20 : 0.479s
40 : 0.935s
80 : 2.821s
160 : 11.694s
320 : 1m30.39s
640: Ran for over 1 hour without terminating
}}}
This uses a couple of attached support files. Apologies for not being able
to reduce further.
{{{
-- Test.hs
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
UndecidableInstances, OverlappingInstances, TypeOperators, DeriveFunctor,
TemplateHaskell #-}
module Test where
import Control.Monad
import Lib
import TH
{-
With n=3, produces
data X1 e = X1 e deriving (Functor)
data X2 e = X2 e deriving (Functor)
data X3 e = X3 e deriving (Functor)
type X = X1 :+: X2 :+: X3
-}
$(let n = 320 in
liftM concat $ sequence [liftM concat $ mapM mkDec $ map (('X':).show)
[1..n]
, makeSumType "X" (map (('X':).show) [1..n])])
data Y0 e = Y0 e deriving ( Functor )
type X' = Y0 :+: X
class Lift f g where
lift' :: f (Fix g) -> Fix g
instance (Lift f g, Lift f' g) => Lift (f :+: f') g where
lift' x = case x of
L e -> lift' e
R e -> lift' e
instance (Functor f, f :<: g) => Lift f g where
lift' = In . inj
cata :: (Functor f) => (f a -> a) -> Fix f -> a
cata f = f . fmap (cata f) . out
lift :: Fix X -> Fix X'
lift = cata lift'
}}}
Virtually all the time is spent in compiling lift. For example, with
n=640, commenting out lift makes it compile in around 2 seconds.
Interestingly, when I add the following code, compilation times only
increase by 10-20%. In the original code where I encountered this issue,
doing so doubles compilation time.
{{{
instance Lift Y0 X where
lift' = undefined
lower :: Fix X' -> Fix X
lower = cata lift'
}}}
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8147>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list