Skip to content

Slow build time on union of enums type as a parameter of generic function. #43899

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
h-joo opened this issue Apr 30, 2021 · 0 comments · Fixed by #43934
Closed

Slow build time on union of enums type as a parameter of generic function. #43899

h-joo opened this issue Apr 30, 2021 · 0 comments · Fixed by #43934
Assignees
Labels
Bug A bug in TypeScript Domain: Big Unions The root cause is ultimately that big unions interact poorly with complex structures Domain: Performance Reports of unusually slow behavior Fix Available A PR has been opened for this issue

Comments

@h-joo
Copy link
Contributor

h-joo commented Apr 30, 2021

Bug Report

Type checking for generic function which the parameter it being specialized with a union of enum and other types has a huge build time.

🔎 Search Terms

big enum, union, performance, slow

🕗 Version & Regression Information

Confirmed with 4.2.4, and recent master branch.( less than one week old)
We started to noticed this slow build from March.

💻 Code

enum BigEnum {
  A0001,
  A0002,
  //  ... until A1998
  A1999,
}
type A = BigEnum | undefined;
// type A = BigEnum | undefined | some_other_type; will cause a drastic increase in build time
function generic<T>(param0: T): void {}
function foo(param: A) {
  generic(param);
  // generic<A>(param); takes almost no time compared to the first statement, since there is no need of type inference.
  // generic(param || something_else); adding another type will also cause a drastic increase in build time
}

🙁 Actual behavior

The build time for a similar code is huge, and it scales up to 10-20 seconds solely for checking the expression similar to generic(param || something_else). The TS library which contains thousands lines of code takes > 200 seconds to build. This is production code and not a made up example.

🙂 Expected behavior

Checking one expression should take much less time, maybe in a scale of hundreds of milliseconds.

Diagnosis

This seems to be a combination of several things.

  1. When you type query on enum type, the TSC type system gives a union of all the enum literals, instead of the enum type. I believe this is by design, and not a bug.
  2. While doing ts.checkCallExpression on call expressions which are generic, it tries to sqaush the type(in the above case type A) if it's union, and try to get a common super type of all it's elements.
  3. If the type given is a huge union, it consumes lots of time in binary search on union types while squshing & figuring out the supertype.
@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Apr 30, 2021
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.4.0 milestone Apr 30, 2021
@weswigham weswigham added the Domain: Big Unions The root cause is ultimately that big unions interact poorly with complex structures label May 3, 2021
@weswigham weswigham added Domain: Performance Reports of unusually slow behavior Fix Available A PR has been opened for this issue Bug A bug in TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels May 3, 2021
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: Big Unions The root cause is ultimately that big unions interact poorly with complex structures Domain: Performance Reports of unusually slow behavior Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants