microsoft / microsoft/TypeScript

Performance issue if many symbols are declared in repeated namespaces

Offen
#53,565 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Experience Enhancement Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne bei addDeclarationToSymbol und dem Aufruf von appendIfUnique und reproduziere dann den Fall eines wiederholten Namespace mithilfe des verlinkten Test-Repositorys und des Playground-Beispiels. Vergleiche das aktuelle und das vorgeschlagene Set-basierte Verhalten und prüfe dabei die Eindeutigkeit der Deklarationen sowie die Compiler-Performance; abgeschlossen ist die Aufgabe, wenn die Regression abgedeckt und die gemeldete Verlangsamung behoben ist, ohne die ausgegebenen Deklarationen zu ändern.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers, performance
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.