镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

perf: Node.getChildren speed regression in ts 5.5 when used at very large scale #59101

Description

@walkerdb

🔎 Search Terms

typescript 5.5 performance, slowdown, typescript-eslint

🕗 Version & Regression Information

⏯ Playground Link

No response

💻 Code

I've put together a repro in a forked version of the sentry monorepo here: walkerdb/sentry#1. It's using the sentry repo only because it's a large public repo that uses typescript-eslint.

🙁 Actual behavior

When running typescript-eslint's type-aware lint rules in a large monorepo with typescript 5.5, we observe lint times between 1.3x to 3x worse than when running the exact same rules and the same config under typescript 5.4. The slowdown seems to be entirely coming from the monomorphized objects change in the ts 5.5 release.

🙂 Expected behavior

There should be no performance impact when moving from typescript 5.4 to 5.5.

Additional information about the issue

We've submitted a bug report to typescript-eslint but we're also reporting here since the slowdown can be pinpointed to a specific typescript change.

Also attaching some before/after update perf traces via 0x that show the extra time is coming largely from typescript internals. The highlighted boxes show the specific part of the process that has ballooned in runtime. I'm happy to share the actual traces with maintainers if they'd be useful in debugging.

ts 5.4 ts 5.5
Screenshot 2024-07-01 at 5 48 38 PM Screenshot 2024-07-01 at 6 04 48 PM

Activity

  1. DanielRosenwasser commented on Jul 2, 2024

    @DanielRosenwasser
    Member

    I didn't get that far on this today, but I believe this is from more time spent in the GC. If you try upping your --max-old-space-size to something way higher, let me know if that alleviates things.

    As an aside, SO much time in your build is being spent on shims running within eslint-plugin-react.

    Time dominated by calls in findVariableByName

    While findVariableByName really should be optimized to not create an intermediate array with variablesInScope, is it possible that you are running on an undesirable input file?

  2. jakebailey commented on Jul 2, 2024

    @jakebailey
    Member

    This is the opposite of expected! Which walk function is that? I'm not familiar with that "walk" function. Traces would be helpful, but walkerdb/sentry#1 is probably enough to give us a lead.

    You may also consider running things via https://www.npmjs.com/package/pprof-it (what Daniel just used above) as it in my experience does a better job attributing time and memory allocations to specific lines of code.

  3. jakebailey commented on Jul 2, 2024

    @jakebailey
    Member

    Hm, my trace doesn't seem to show that particular code as to blame:

    image

    Walker Boyle (@walkerdb) What tool did you use to find your result?

  4. jakebailey commented on Jul 2, 2024

    @jakebailey
    Member

    I timed this, and in 5.5, it's 100s, but 5.4 is 91s; not 2-3x slower from what I can tell...

  5. jakebailey commented on Jul 2, 2024

    @jakebailey
    Member

    A second run of 5.4 was 100s too. Not sure what's going on here. What version of Node are you using?

  6. jakebailey commented on Jul 2, 2024

    @jakebailey
    Member

    I was using Node 22; switching down to Node 18 shows a worse regression:

    // 5.4.5
    total time:  160.75s
    user time:   212.16s
    system time: 4.96s
    CPU percent: 135%
    max memory:  3946 MB
    
    // 5.5.3
    total time:  217.70s
    user time:   292.33s
    system time: 6.36s
    CPU percent: 137%
    max memory:  3995 MB
    

    Not 2-3x but very much farther apart than Node 22.

    Unfortunately I'm now going to be gone until next week, so this will just have to eat me up inside until then...

  7. walkerdb commented on Jul 2, 2024

    @walkerdb
    Author

    Hi Jake Bailey (@jakebailey)! Sorry, I should have clarified a few things:

    1. the traces above were generated using 0x, but on our private monorepo, which has a 2.5x slowdown when running our typed lints under ts 5.5 instead of 5.4. I used sentry as a public repro but its slowdown was only ~1.3x on my machine.
    2. in our private monorepo we run lint with essentially unlimited max-old-space and also with higher max-semi-space since we run into gc issues with young gen / scavenge as well at our size.
    3. we are indeed running node 18! Likely will update to 22 by end of year but that's a major undertaking for us.

    to Daniel Rosenwasser (@DanielRosenwasser) I'm not a part of sentry, I was just using that repo as an example repro since ours is private.

  8. walkerdb commented on Jul 2, 2024

    @walkerdb
    Author

    the types in Notion's private monorepo can be quite complex, and I suspect are close to a pathological case for some typescript perf behavior, which may help explain the 2.5x slowdown we were observing. I'll see if I can hack running the same checks under node 22 to see if the timings change there much.

  9. jakebailey commented on Jul 2, 2024

    @jakebailey
    Member

    Ran Node 18, and the results are very different from #59101 (comment):

    image

    That is an incredible amount of GC time, along with the badness Daniel noted above. Given the difference between Node 18 and Node 22 on this being in that shim code, I'm not 100% certain that this repro is representative of the repo you're testing internally, unfortunately...

    Would you be able to run pprof-it on your own codebase? Screenshots of flame graphs and such should not expose any details, but you can also run it with PPROF_SANITIZE=on to sanitize the output for sharing (as that will remove any paths from the profile).

  10. walkerdb commented on Jul 2, 2024

    @walkerdb
    Author

    Jake Bailey (@jakebailey) I'll give pprof-it a try, ty!

  11. walkerdb commented on Jul 2, 2024

    @walkerdb
    Author

    here's my pprof result for typescript 5.5.2 on node 18.18. I'll also upload one for typescript 5.4 in a sec
    pprof-time-typescript-55.pb.gz
    pprof-heap-typescript-55.pb.gz

  12. walkerdb commented on Jul 2, 2024

    @walkerdb
    Author

    pprof results for the exact same run but using typescript 5.4.5 on node 18.18 . This is significantly faster, and matches our expected run time from prior to the 5.5 update
    pprof-time-typescript-54.pb.gz
    pprof-heap-typescript-54.pb.gz

  13. walkerdb commented on Jul 2, 2024

    @walkerdb
    Author

    last run, with typescript 5.5.2 and node 22.3.0. Running under a newer node version doesn't seem to actually be much faster in this case?
    pprof-time-typescript-55-node-22.pb.gz
    pprof-heap-typescript-55-node-22.pb.gz

  14. 16 remaining items

  15. walkerdb commented on Jul 6, 2024

    @walkerdb
    Author

    Can do, thank you for all your help! Is there any specific feedback that would help on the new version other than whether tsserver requests like getProgram, getSemanticDiagnostics, getCompletionsAtPosition etc still seem to work and are just as responsive as before? (we track perf metrics for each of them via a custom plugin so it should be pretty easy for us to tell whether there's been any major regression there)

  16. jakebailey commented on Jul 8, 2024

    @jakebailey
    Member

    we track perf metrics for each of them via a custom plugin so it should be pretty easy for us to tell whether there's been any major regression there

    This sounds amazing, and I absolutely want to hear more about this. This is the first we've heard of someone tracking this to this extent so anything is awesome.

  17. maschwenk commented on Jul 8, 2024

    @maschwenk
    Contributor

    Had a huge typescript-eslint regression just like this in our very large monolith. Had a similar idea of bumping --max-old-space-size but that didn't work:

    https://discord.com/channels/1026804805894672454/1254556633556713553/1255160613441769683

    Setting my typescript dependency to "typescript": "npm:@typescript-deploys/pr-build@5.6.0-pr-59154-2", fixed the issue, and actually seems a bit faster than baseline!

  18. DanielRosenwasser commented on Jul 8, 2024

    @DanielRosenwasser
    Member

    Hey all, this is fixed in the main branch but I want it to prove itself out for a bit. If you use the nightly build tomorrow (especially in the editor https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next), that would go a long way.

    If you are actually able to measure, we are specifically looking for differences in memory usage, changes in editor operation delays, as well as changes in variance in delays.

    If things feel good, we can cherry-pick the change back into 5.5.

  19. walkerdb commented on Jul 9, 2024

    @walkerdb
    Author

    Daniel Rosenwasser (@DanielRosenwasser) can do! I'll get a test group going internally tomorrow, will see if metrics move much. We do also track total tsserver memory usage, should be able to see if that moves much under the new version as well.

    Jake Bailey (@jakebailey) happy to chat more about our tsserver observability setup! Could talk sync / show a few dashboards if you're interested?

  20. walkerdb commented on Jul 9, 2024

    @walkerdb
    Author

    and thank you both again for moving so fast on this, much appreciated!

  21. JoshuaKGoldberg commented on Jul 10, 2024

    @JoshuaKGoldberg
    Contributor

    +1 from the typescript-eslint side, we really appreciate it! Thanks so much for the fast follow and (very interesting) deep dive everyone!

  22. walkerdb commented on Jul 12, 2024

    @walkerdb
    Author

    following up to say we haven't noticed any serious perf regressions in IDE usage so far. We haven't had the participation numbers to say much more than that though.

  23. maschwenk commented on Jul 15, 2024

    @maschwenk
    Contributor

    Likewise on stability in my testing in very large monorepo (with a very large monolith). Curious if there are plans on a 5.5 backport? Or still targeting 5.6?

  24. jakebailey commented on Jul 15, 2024

    @jakebailey
    Member

    The backport is open here: #59211

  25. DanielRosenwasser commented on Jul 22, 2024

    @DanielRosenwasser
    Member

    TypeScript 5.5.4 should contain the fix - thanks for reporting everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Domain: PerformanceReports of unusually slow behaviorFix AvailableA PR has been opened for this issueNeeds InvestigationThis issue needs a team member to investigate its status.Recent RegressionThis is a new regression just found in the last major/minor version of TypeScript.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions