Skip to content

Degenerate compiler performance when processing large unions #37744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nomcopter opened this issue Apr 1, 2020 · 2 comments · Fixed by #37749
Closed

Degenerate compiler performance when processing large unions #37744

nomcopter opened this issue Apr 1, 2020 · 2 comments · Fixed by #37749
Labels
Bug A bug in TypeScript Domain: Performance Reports of unusually slow behavior

Comments

@nomcopter
Copy link

nomcopter commented Apr 1, 2020

TypeScript Version: 3.9.0-dev.20200328

Search Terms: large union, performance, indexed access

Code

type BigUnion = {
  name: '1';
  children: BigUnion[];
} | {
  name: '2';
  children: BigUnion[];
  // 1000 more .......
} | {
  name: '1003';
  children: BigUnion[];
};

type DiscriminateUnion<T, K extends keyof T, V extends T[K]> = T extends Record<K, V> ? T : never;

type WithName<T extends BigUnion['name']> = DiscriminateUnion<BigUnion, 'name', T>;

type ChildrenOf<T extends BigUnion> = T['children'][number];

export function makeThing<T extends BigUnion['name']>(
  name: T,
  children: ChildrenOf<WithName<T>>[] = [],
) { }

Expected behavior:
It compiles reasonably quickly.

Note: This happens even when children is not a recursive reference. In my project children is an array of specific subtypes of BigUnion but it is closed source.

Actual behavior:
It takes over 90s to compile on a 2019 Macbook Pro using node or the playground link.

  % tsc --noEmit --diagnostics --extendedDiagnostics --generateCpuProfile out.prof simple.ts
Files:                           6
Lines:                       27987
Nodes:                      122358
Identifiers:                 44171
Symbols:                     32200
Types:                       19618
Memory used:               234674K
Assignability cache size:  2055962
Identity cache size:             0
Subtype cache size:              0
Strict subtype cache size:       0
I/O Read time:               0.01s
Parse time:                  0.30s
Program time:                0.32s
Bind time:                   0.15s
Check time:                 97.49s
Total time:                 97.95s
✨  Done in 98.49s.

cpuprofile.prof.zip

Playground Link: Playground Link

Related Issues: #29350

@weswigham
Copy link
Member

Ohhh, 86.44% of total time spent in getRegularTypeOfLiteralType? Yeah, that sounds degenerate. Looks like we don't cache that calculation, so we're re-iterating over the massive union every time.

@weswigham weswigham added Bug A bug in TypeScript Domain: Performance Reports of unusually slow behavior labels Apr 2, 2020
@nomcopter
Copy link
Author

Thanks for a quick fix - clever optimizations!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Domain: Performance Reports of unusually slow behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants