microsoft / microsoft/TypeScript

Performance issue if many symbols are declared in repeated namespaces

Open
#53,565 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Experience Enhancement Suggestion
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

Bug Report

🔎 Search Terms

addDeclarationToSymbol, pushIfUnique, performance namespace bind

🕗 Version & Regression Information

This is the behavior in every version I tried: v4.9.4, v5.0.2

⏯ Playground Link

Repro in: https://github.com/frigus02/test-ts-add-declaration-to-symbol-set

Playground link with relevant code

💻 Code

We have a .d.ts generator that emits symbols in nested namespaces. For simplicity the generator always emits the entire namespace. Example:

declare namespace __generated.foo.bar {
  export class A {}
}
declare namespace __generated.foo.bar {
  export class B {}
}
declare namespace __generated.foo.bar.baz {
  export class C {}
}
// Repeat that a few thousand times

It seems this pattern runs into a performance issue inside addDeclarationToSymbol. It calls appendIfUnique(symbol.declarations, node), which iterates through the symbol.declarations array. The code above leads to lots of declarations of the symbols __generated, __generated.foo, etc.

The patch tsc_patch.diff uses a Set rather than iterating the array. This seems to speed up the build time significantly.

🙁 Actual behavior / 🙂 Expected behavior

The build is slower than it could be. A real project (which I can't share publicly) takes ~40 seconds to build currently. With the patch is takes ~16 seconds.

The example in https://github.com/frigus02/test-ts-add-declaration-to-symbol-set shows a "Total time" of 5.61s vs 1.19s.

Question

I realize that we could change the code generator to fix this. Unfortunately that is trickier than it seems and we likely can't do that in the next ~year.

Do you think such a patch (using a Set) is feasible here? If yes, I'd be happy to prepare a PR.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at addDeclarationToSymbol and its appendIfUnique call, then reproduce the repeated-namespace case using the linked test repository and Playground example. Compare the current and proposed Set-based behavior, checking declaration uniqueness and compiler performance; done means the regression is covered and the reported slowdown is addressed without changing emitted declarations.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.