[GHC] #11375: Type aliases twice as slow to compile as closed type families.

#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

#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler (Type | Version: 8.1 checker) | Resolution: | Keywords: Operating System: MacOS X | Architecture: aarch64 Type of failure: Compile-time | Test Case: performance bug | Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by danilo2: Old description:
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.
New description: 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: 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 162,249 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#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler (Type | Version: 8.1 checker) | Resolution: | Keywords: Operating System: MacOS X | Architecture: aarch64 Type of failure: Compile-time | Test Case: performance bug | Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by danilo2: Old description:
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: 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 162,249 using type families. This is really interesting thing and it seems related to the linked bug above.
New description: 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: 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 aliase (used in one single place (!)) produces (100 x) more coertions than type families: `16,383,834` vs `162,249`. This is really interesting thing and it seems related to the linked bug above. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11375#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler (Type | Version: 8.1 checker) | Resolution: | Keywords: Operating System: MacOS X | Architecture: aarch64 Type of failure: Compile-time | Test Case: performance bug | Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): That is mysterious. I have absolutely no idea what is happening. So a way to reproduce would indeed be useful! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11375#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler (Type | Version: 8.1 checker) | Resolution: | Keywords: Operating System: MacOS X | Architecture: aarch64 Type of failure: Compile-time | Test Case: performance bug | Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by danilo2): Ok, I didnt managed tocut the minimal example out, but I'm on right way, stay tuned! :) I'm writing this comment only to let you know that I remember about it and keep it as an important task and trying to find a little time for it :) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11375#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler (Type | Version: 8.1 checker) | Resolution: | Keywords: Operating System: MacOS X | Architecture: aarch64 Type of failure: Compile-time | Test Case: performance bug | Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by jstolarek): * cc: jstolarek (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11375#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: Type: bug | Status: infoneeded Priority: high | Milestone: Component: Compiler (Type | Version: 8.1 checker) | Resolution: | Keywords: TypeFamilies Operating System: MacOS X | Architecture: aarch64 Type of failure: Compile-time | Test Case: performance bug | Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: new => infoneeded Comment: danilo2, any word on this? It would be great to have a lead on this. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11375#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: (none) Type: bug | Status: infoneeded Priority: high | Milestone: Component: Compiler (Type | Version: 8.1 checker) | Resolution: | Keywords: TypeFamilies Operating System: MacOS X | Architecture: aarch64 Type of failure: Compile-time | Test Case: performance bug | Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by danilo2): @bgmari, I'm sorry, due to completely lack of time while moving to new back-end architecture, we didn't hunted it down and it stopped slowing us down. Let's close this issue, as fast as it appears again, I'll prepare minimal example. I'm really sorry I did not cut it down that time. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11375#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#11375: Type aliases twice as slow to compile as closed type families. -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: (none) Type: bug | Status: closed Priority: high | Milestone: Component: Compiler (Type | Version: 8.1 checker) | Resolution: invalid | Keywords: TypeFamilies Operating System: MacOS X | Architecture: aarch64 Type of failure: Compile-time | Test Case: performance bug | Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: infoneeded => closed * resolution: => invalid Comment: It's quite alright! Thanks for reporting it and let's hope we can nail it in the future. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11375#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC