
#9630: compile-time performance regression (probably due to Generics) -------------------------------------+------------------------------------- Reporter: hvr | Owner: simonpj Type: bug | Status: new Priority: high | Milestone: 8.0.1 Component: Compiler | Version: 7.9 Resolution: | Keywords: deriving-perf 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): Wiki Page: | -------------------------------------+------------------------------------- Comment (by ezyang): I did some investigation related to this bug on GHC 7.10.3-ish and binary 0.7.5.0 (yes it's old, but I didn't see any more recent relevant commits; and it's what GHC is bootstrapping with). Here are some partial findings: 1. I can trigger bad constant factors this data type: {{{ {-# LANGUAGE DeriveGeneric #-} module A where import Data.Binary import GHC.Generics data T = T () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () deriving Generic instance Binary T }}} {{{ ezyang@sabre:~/Dev/labs$ time $DEV/ghc-7.10-frontend-plugins/usr/bin/ghc --make Bin.hs -O2 -fforce-recomp -fliberate-case-threshold=1000 [1 of 1] Compiling A ( Bin.hs, Bin.o ) real 0m7.369s user 0m6.408s sys 0m0.224s ezyang@sabre:~/Dev/labs$ time $DEV/ghc-7.10-frontend-plugins/usr/bin/ghc --make Bin.hs -O0 -fforce-recomp -fliberate-case-threshold=1000 [1 of 1] Compiling A ( Bin.hs, Bin.o ) real 0m0.881s user 0m0.776s sys 0m0.080s }}} 2. The problem gets worse if you have explicit field names, something like a x2 factor. {{{ data T = T () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () () deriving Generic -- versus data T = T { f0 :: (), f1 :: (), f2 :: (), f3 :: (), f4 :: (), f5 :: (), f6 :: (), f7 :: (), f8 :: (), f9 :: (), f10 :: (), f11 :: (), f12 :: (), f13 :: (), f14 :: (), f15 :: (), f16 :: (), f17 :: (), f18 :: (), f19 :: (), f20 :: (), f21 :: (), f22 :: (), f23 :: (), f24 :: (), f25 :: (), f26 :: (), f27 :: (), f28 :: (), f29 :: (), f30 :: (), f31 :: (), f32 :: (), f33 :: (), f34 :: (), f35 :: (), f36 :: (), f37 :: (), f38 :: (), f39 :: () } deriving (Generic) }}} {{{ ezyang@sabre:~/Dev/labs$ time $DEV/ghc-7.10-frontend-plugins/usr/bin/ghc --make Bin.hs -O -fforce-recomp -fliberate-case-threshold=1000 [1 of 1] Compiling A ( Bin.hs, Bin.o ) real 0m2.649s user 0m2.520s sys 0m0.080s ezyang@sabre:~/Dev/labs$ time $DEV/ghc-7.10-frontend-plugins/usr/bin/ghc --make Bin.hs -O -fforce-recomp -fliberate-case-threshold=1000 [1 of 1] Compiling A ( Bin.hs, Bin.o ) real 0m4.990s user 0m4.824s sys 0m0.144s }}} It's NOT just generic deriving; the generic deriving is still pretty speedy, honestly. 3. If you inline all of Binary's class definitions into the same file, things speed up. Comparing the two cases, it seems that when we cross- module compile, GHC does more inlining and more optimization, and it takes longer. This is something like a 30% factor. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9630#comment:21 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler