
#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler | Version: 8.1 (Type checker) | Keywords: | Operating System: MacOS X Architecture: aarch64 | Type of failure: Compile-time | performance bug Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Hello guys! This bug is awkard at last to me. So I notiiced today, that using type aliases in my code takes twice as long to copile than using closed type families with just single member. So to be most precise - when I replace the following line: {{{ type XQ1 m a = Targets (Match m a) }}} with {{{ type family XQ1 m a where XQ1 m a = Targets (Match m a) }}} the compilation time drops from 15s to 7s (this type alias is heavily used across the application). I think it could be somehow related to the famous #8095 bug, but I can of course be wrong here. Unfortunetally the codebase is pretty big and its not so easy to make a minimal example, but I'll try to work on it during the upcoming weekend (please notify me if that would not be necessary). And some statistics from `-dshow-passes`: When using type alias: {{{ *** Parser: *** Renamer/typechecker: *** Desugar: Result size of Desugar (after optimization) = {terms: 10,303, types: 66,949, coercions: 16,383,834} *** Simplifier: Result size of Simplifier iteration=1 = {terms: 10,722, types: 75,391, coercions: 16,507,338} Result size of Simplifier iteration=2 = {terms: 10,550, types: 74,437, coercions: 16,504,770} Result size of Simplifier iteration=3 = {terms: 10,543, types: 74,347, coercions: 16,504,734} Result size of Simplifier = {terms: 10,543, types: 74,347, coercions: 16,504,630} *** Tidy Core: Result size of Tidy Core = {terms: 10,846, types: 75,522, coercions: 16,504,729} *** CorePrep: Result size of CorePrep = {terms: 14,823, types: 96,430, coercions: 16,504,729} *** ByteCodeGen: Upsweep completely successful. *** Deleting temp files: Warning: deleting non-existent /var/folders/y9/km24zv3d4yl711mwv85vwljc0000gp/T/ghc64965_0/ghc_95.c Warning: deleting non-existent /var/folders/y9/km24zv3d4yl711mwv85vwljc0000gp/T/ghc64965_0/ghc_94.o Ok, modules loaded: Prologue, Type.Bool, Type.Container, Type.List, Type.Set, Data.Cata, Type.Promotion, Data.Bits.Mask, Control.Monad.State.Dependent, Control.Monad.Poly, Control.Applicative.Poly, Type.Regex, Type.Either, Data.Reprx, Data.Impossible, Type.Cache.TH, Main, Control.Lens.Utils, Control.Lens.Wrapped.Utils, Data.Text.CodeBuilder, Data.Text.CodeBuilder.Tok, Data.Text.CodeBuilder.Builder, Data.Text.CodeBuilder.Doc, Data.Binary.Instances.Missing, Data.Default.Instances.Missing, Data.String.Class, Data.Text.Class, Data.Convert, Data.Layer, Data.Container.Class, Data.Container.List, Data.Functor.Utils, Type.Operators, Type.Show, Type.Wrapped, Data.Container.Opts, Data.Container.Poly, Data.Convert.Base, Data.Convert.Instances, Data.Convert.Instances.Map, Data.Convert.Instances.Num, Data.Convert.Instances.Text, Data.Convert.Instances.TH, Data.Convert.Bound, Data.Bits.Base. *** Parser: *** Desugar: *** Simplify: *** CorePrep: *** ByteCodeGen: ... }}} and with type families: {{{ *** Parser: *** Renamer/typechecker: *** Desugar: Result size of Desugar (after optimization) = {terms: 310, types: 867, coercions: 78} *** Simplifier: Result size of Simplifier iteration=1 = {terms: 301, types: 878, coercions: 296} Result size of Simplifier = {terms: 301, types: 878, coercions: 293} *** Tidy Core: Result size of Tidy Core = {terms: 337, types: 1,002, coercions: 293} *** CorePrep: Result size of CorePrep = {terms: 475, types: 1,305, coercions: 293} *** ByteCodeGen: *** Deleting temp files: Warning: deleting non-existent /var/folders/y9/km24zv3d4yl711mwv85vwljc0000gp/T/ghc64863_0/ghc_93.c Warning: deleting non-existent /var/folders/y9/km24zv3d4yl711mwv85vwljc0000gp/T/ghc64863_0/ghc_92.o compile: input file /var/folders/y9/km24zv3d4yl711mwv85vwljc0000gp/T/ghc64863_0/ghc_1.hscpp *** Checking old interface for Main: [45 of 45] Compiling Main ( /Users/wdanilo/dev/hs/public/variants/Main.hs, interpreted ) *** Parser: *** Renamer/typechecker: *** Desugar: Result size of Desugar (after optimization) = {terms: 10,303, types: 67,609, coercions: 162,249} *** Simplifier: Result size of Simplifier iteration=1 = {terms: 10,722, types: 75,721, coercions: 323,027} Result size of Simplifier iteration=2 = {terms: 10,550, types: 74,767, coercions: 320,473} Result size of Simplifier iteration=3 = {terms: 10,543, types: 74,677, coercions: 320,437} Result size of Simplifier = {terms: 10,543, types: 74,677, coercions: 320,333} *** Tidy Core: Result size of Tidy Core = {terms: 10,846, types: 75,852, coercions: 320,432} *** CorePrep: Result size of CorePrep = {terms: 14,823, types: 96,760, coercions: 320,432} *** ByteCodeGen: Upsweep completely successful. *** Deleting temp files: Warning: deleting non-existent /var/folders/y9/km24zv3d4yl711mwv85vwljc0000gp/T/ghc64863_0/ghc_95.c Warning: deleting non-existent /var/folders/y9/km24zv3d4yl711mwv85vwljc0000gp/T/ghc64863_0/ghc_94.o Ok, modules loaded: Prologue, Type.Bool, Type.Container, Type.List, Type.Set, Data.Cata, Type.Promotion, Data.Bits.Mask, Control.Monad.State.Dependent, Control.Monad.Poly, Control.Applicative.Poly, Type.Regex, Type.Either, Data.Reprx, Data.Impossible, Type.Cache.TH, Main, Control.Lens.Utils, Control.Lens.Wrapped.Utils, Data.Text.CodeBuilder, Data.Text.CodeBuilder.Tok, Data.Text.CodeBuilder.Builder, Data.Text.CodeBuilder.Doc, Data.Binary.Instances.Missing, Data.Default.Instances.Missing, Data.String.Class, Data.Text.Class, Data.Convert, Data.Layer, Data.Container.Class, Data.Container.List, Data.Functor.Utils, Type.Operators, Type.Show, Type.Wrapped, Data.Container.Opts, Data.Container.Poly, Data.Convert.Base, Data.Convert.Instances, Data.Convert.Instances.Map, Data.Convert.Instances.Num, Data.Convert.Instances.Text, Data.Convert.Instances.TH, Data.Convert.Bound, Data.Bits.Base. *** Parser: *** Desugar: *** Simplify: *** CorePrep: *** ByteCodeGen: ... }}} As we can see the type aliases produce much more coertions: 16,383,834 vs 78 using type families. This is really interesting thing and it seems related to the linked bug above. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11375 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler