Skip to content

Regression in optimisation time of functions with many patterns (6.12 to 7.4)?

In our project, we build (via TH) some not-trivial data structures, including custom serialisation. After growing the number of constructors significantly, compiling same code with ghc 7.4/7.6 is about 10 times slower than with ghc 6.12.

Narrowing this down on a simpler test case, it turns out that TH is not the cause, just the optimisation of the generated code.

The attached Generator.hs file generates a simple data structure (our project is using a much smaller number of constructors, but with more complex data types, and the result is the same):

data F
  = F1 {fldF1 :: Int} |
    F2 {fldF2 :: Int} |
    F3 {fldF3 :: Int} |
    F4 {fldF4 :: Int} |
    F5 {fldF5 :: Int} |
  … deriving (Eq, Show, Read)

prettyF :: F -> String
prettyF (F1 v) = show v
prettyF (F2 v) = show v

The main.hs file just calls this splice and then does a trivial use of prettyF.

Compiling this with a variable number of constructors, with -O:

Constructors 6.12 7.6
50 2.45s 4.10s
100 4.40s 10.60s
200 8.45s 33.30s
400 16.90s 121.00s
800 35.95s 514.50s

As you can see, 6.12 looks liniar in the number of constructors, whereas 7.6 is not anymore (at least above 100 constructors).

Compiling without -O makes things sane again:

Constructors 6.12 7.6
50 1.40s 1.97s
100 2.45s 2.70s
200 4.50s 4.95s
400 8.95s 9.55s
800 18.25s 19.10s

After some more investigation, it turns out that just our function function (prettyF) with no automatic instances is cheap, compiling/deriving Eq/Show is also cheap, but Read is very expensive (all numbers with ghc 7.6):

Constructors No instances Eq Show Read
50 0.75s 0.90s 1.20s 2.95s
100 0.85s 1.00s 1.70s 6.80s
200 1.20s 1.45s 2.85s 19.15s
400 2.05s 2.50s 5.40s 64.45s
800 4.30s 5.40s 11.65s 259.40s

So I believe this is about optimisation of complex functions with many patterns/case statements. 6.12 seems nicely liniar, whereas 7.4/7.6 exhibit a much worse behaviour.

This might be a known issue, or even a non-issue ("Don't use Read for complex types"), but I thought it's better to report it. I don't have the skills to look at the core result, and see if it's different or not between 6.12/7.6, sorry.

Trac metadata
Trac field Value
Version 7.6.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information