-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Cache ts.program between linted files #361
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
Cache ts.program between linted files #361
Conversation
Codecov Report
@@ Coverage Diff @@
## master #361 +/- ##
==========================================
- Coverage 97.24% 97.21% -0.03%
==========================================
Files 67 67
Lines 2357 2333 -24
Branches 336 335 -1
==========================================
- Hits 2292 2268 -24
Misses 44 44
Partials 21 21
|
Thanks so much for looking into this @dsgkirkby! I was on site at Microsoft in Redmond today and paired with @uniqueiniquity on this area of the codebase. We just merged an initial fix here: #367 There is still more work being done than in this PR, so it will be slower, but we would be grateful if you wouldn't mind installing the new canary version ( Please could you also provide details on how you are benchmarking? We can then assess where we're at and see the updated delta between your PR and the change we made today. Thanks again! |
@JamesHenry on My benchmarking is simply running it normally on my laptop against the various repos (in the case of our private repo, via The approach that you've taken is fundamentally different than what I've done here, as I completely removed the usage of watch mode and compiled normally; while the approach I took seems simpler overall (imo) it could also be somewhat risky to ship this as it's a larger change. There are some small, utility-like parts of this PR that are probably worth keeping either way (unifying path resolution to a single codepath, choosing the first program that is able to parse the file rather than the first that's defined, the added tests), so one option if you'd like to keep the current approach would be for me to strip most of this PR and just leave that. |
Hi @dsgkirkby, sorry for taking so long to get back to you on this. I do think we should keep the tests you added, since they're definitely adding coverage in a helpful way. While I do appreciate the simplicity and clarity of your approach, I think we (maybe unfortunately) have to keep the existing approach. In particular, all this overhead is really just set up to manage two tricky pieces - The usage of the Sorry for dumping that wall of text, but I hope that explains a little better why this seemingly heavy approach was needed. I really appreciate that you took the time to try to address the perf issue, and I think it would be great if we could still get those test changes in. Thanks again! |
@JamesHenry @uniqueiniquity do we have any other progress on that matter to mention here? I'm in the process of migrating from a legacy tslint + eslint setup to a eslint only setup but that has doubled our linting time from 6 mins to 12 mins and it looks like related with that matter here. |
@mistic Which version of typescript-estree are you using? There should be improvements in v1.5.0 or higher. |
@uniqueiniquity according my
I did some changes according to some other users' feedback also having that problem and as I was not using any typescript linting rule which required type information I just set the @uniqueiniquity do you think there would be any solution to solve that performance issue soon in the future in case we wanna use rules that actually requires type information and still doesn't increase too much the linting time? I think one thing that might be helpful to reduce the number of affected users would be trying to understand by the given rules in a configuration if there is any of them that requires type information. If there is none just automatically set/override Thanks for the quick answer on it @uniqueiniquity ! 👍 |
Thanks for confirming, @mistic! I like the idea of being able to only do the extra work if any rules with type info are actually used. Currently, that information isn't available to the parser, so we would have to make a change in the core ESLint project to enable that. But it's certainly something worth exploring. |
For reference (@uniqueiniquity): #389 |
Background
This improves the performance issues outlined in #243.
Approach
Rather than creating a watch program and having it parse each file as we lint it, instead we create a
ts.program
for each project and cache them.When attempting to parse a file, we go through each created program and attempt to parse the given filename with it.
Results
These are on my machine (2018 MBP w/ i7, 16GB RAM)
This repo w/o project
master: 3.40s
new: 3.24s
This repo w/ project
master: 13.34s
new: 5.68s
Single file in this repo w/ project
master: 10.83s
new: 4.92s
The repo originally mentioned in #243 w/ project
master: 50.72s
new: 9.94s
Limitations
If a file that's being linted isn't included in the given tsconfig, performance remains poor, as we fall back to the current behaviour of parsing that file in isolation; eslint/eslint#11222 might be able to help with this once it's shipped. This seems very much like an edge case though.