microsoft / microsoft/TypeScript

Performance issue if many symbols are declared in repeated namespaces

オープン
#53,565 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Experience Enhancement Suggestion
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
1日 19時間
マージ済み PR(30日)
117

説明

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.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

addDeclarationToSymbol とその appendIfUnique 呼び出しから始め、リンクされたテストリポジトリと Playground の例を使って、namespace が繰り返されるケースを再現します。現在の Set ベースの動作と提案された Set ベースの動作を比較し、宣言の一意性とコンパイラのパフォーマンスを確認します。回帰がカバーされ、出力される宣言を変更せずに報告された速度低下が解消されていれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers, performance
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。