Skip to content

Extremely slow compilation; resolving generics? #30781

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
mmorearty opened this issue Apr 5, 2019 · 7 comments
Closed

Extremely slow compilation; resolving generics? #30781

mmorearty opened this issue Apr 5, 2019 · 7 comments
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status. Rescheduled This issue was previously scheduled to an earlier milestone

Comments

@mmorearty
Copy link
Contributor

TypeScript Version: 3.5.0-dev.20190405

Search Terms: slow compilation generics

Code

example.zip

Expected behavior:

Compilation should take a reasonable amount of time

Actual behavior:

On my MacBook Pro, compilation takes 31 seconds before any error messages appear.

I suspect this may have to do with the compiler trying to resolve generic types. A few comments:

  • The code is hard to read, because I had to obfuscate it. Sorry about that.
  • This is a hacked-up version of some of our real code. The real version compiles successfully (unlike this hacked-up one which produces errors). This is based on a TypeScript module we have that takes two minutes to compile. It only has 19,000 lines of .ts files plus 100,000 lines of .d.ts files. Most of our similar-sized modules take about 30 seconds.
  • Take a look at the declaration of create at the bottom of src/sb_by_hr.ts. If you take out all the fancy generics, and instead put export const create = React.createFactory(Component);, compilation takes only 2 seconds.
  • You'll notice that lib/a.d.ts has a fairly large number of type declarations. The declare module "a/dm/ps" section is about 2800 lines of one- or two-line type declarations, and declare module "a/dm/pm" is about 3800. If you delete large chunks of type declarations from either one of those blocks, the compilation times goes down. It seems to go down. For example, if you delete about half of the types from "a/dm/ps", compilation time goes from 31 seconds down to 11.8 seconds. Similarly, if you delete about half of the types from "a/dm/pm", the time goes down to 11 seconds.

Related Issues:

These may or may not be related:

@Veetaha
Copy link

Veetaha commented Apr 5, 2019

I would even say more, my project compilation fails with heap overflow.

This issue is somewhat connected to #30663

@mmorearty
Copy link
Contributor Author

Thanks for the links, @Veetaha, that's interesting. But I don't think my issue is directly related to #30663, because of the version where the slowdown started. That issue is a new one that appeared in 3.4.1. I just did some testing with old versions, and the slowdown for my issue was introduced all the way back in 2.6.1 (a very long time ago).

@richard-viney
Copy link

I've encountered what sounds like a similar performance issue in 3.4.5 that persists in 3.5-rc.

Repo to reproduce the problem is here: https://github.com/richard-viney/typescript-performance-issue

It's easy to get compilation times up into the 10-20-30 second mark or more just by duplicating a single line of code. There are two workarounds documented in the README, both related to generics.

Trying to reduce to a simpler self-contained repro case proved tricky, as reducing the amount of type definitions being pulled in also progressively reduced the performance problem, as if there was a scaling issue inside the compiler itself where internal lookup/resolution times aren't scaling as they should.

@richard-viney
Copy link

I should also add that we were stuck on 3.2.x for a while because of this issue, it originally cropped up in TS 3.3.0 and we've ended up working around it in our app code (by using fewer generics) so that we can stay on the latest TS release.

@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.7.0 milestone Aug 22, 2019
@orta orta added the Rescheduled This issue was previously scheduled to an earlier milestone label May 12, 2020
@orta orta modified the milestones: TypeScript 3.9.1, TypeScript 4.0 May 12, 2020
@orta
Copy link
Contributor

orta commented Jul 13, 2020

Hi folks, sorry this one took a while to look at - I explored it a few times and I've come back to give it a shot for 4.0.

Some notes: the example.zip still is about 60s when using the generics:

Files:                          15
Lines:                       35448
Nodes:                      171313
Identifiers:                 59172
Symbols:                     85089
Types:                       39287
Memory used:               772879K
Assignability cache size:    53456
Identity cache size:            12
Subtype cache size:         214809
Strict subtype cache size: 7305744
I/O Read time:               0.01s
Parse time:                  0.51s
Program time:                0.57s
Bind time:                   0.31s
Check time:                 52.88s
transformTime time:          0.03s
commentTime time:            0.00s
I/O Write time:              0.00s
printTime time:              0.04s
Emit time:                   0.04s
Total time:                 53.80s

vs 5 without

Files:                          15
Lines:                       35448
Nodes:                      171267
Identifiers:                 59152
Symbols:                     84954
Types:                       30552
Memory used:               127370K
Assignability cache size:    53396
Identity cache size:            12
Subtype cache size:              9
Strict subtype cache size:       0
I/O Read time:               0.01s
Parse time:                  0.53s
Program time:                0.58s
Bind time:                   0.32s
Check time:                  2.90s
transformTime time:          0.02s
commentTime time:            0.00s
I/O Write time:              0.00s
printTime time:              0.04s
Emit time:                   0.04s
Total time:                  3.84s

Pretty wild difference in the subtype checking caches between them.

@richard-viney
Copy link

FYI the repro case that I mentioned above back on 18 May 2019 has been resolved by an intervening TS release (not sure which one though).

@orta
Copy link
Contributor

orta commented Jul 21, 2020

OK, I re-ran the checks with wes against different versions of TypeScript including nightly and it looks like this is fixed in 3.9 and still is in master

For 3.6, 3.8 and 3.8 we were looking at 60s but for 3.9 and nightly it was ~2s for the example. We did a bunch of perf work on handling large unions then which likely are the candidate for the fix 👍

@orta orta closed this as completed Jul 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status. Rescheduled This issue was previously scheduled to an earlier milestone
Projects
None yet
Development

No branches or pull requests

6 participants