Skip to content

astgen: opt-in timing diagnostics for TypeScript type generation - #24

Merged
prabhu merged 3 commits into
mainfrom
perf/astgen-typegen
Oct 24, 2026
Merged

prabhu merged 3 commits into
mainfrom
perf/astgen-typegen

Conversation

@prabhu

@prabhu prabhu commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Typed astgen runs on cdxgen take about 75 minutes, and almost all of that is one file, lib/cli/index.js. This adds opt-in diagnostics that show where type generation spends its time. It doesn't make anything faster, because we didn't find a speedup that keeps the output the same.

With ASTGEN_TYPE_TIMING=1, astgen prints one stderr line per file with:

  • wall time;
  • nodes visited;
  • checker calls and the time spent in them;
  • how often the same node was queried again;
  • the node kinds queried most.

ASTGEN_TYPE_TIMING_SLOW_MS=n also lists the queries that took longer than n ms, with the file and line of each. With the variable unset, nothing changes. npm test passes, and typemaps and ASTs are byte-identical to main on juice-shop, bulletproof-react, nestjs-realworld, node-express-boilerplate, node-express-realworld, twelve synthetic projects and a full cdxgen run.

What the diagnostics found: lib/cli/index.js reassigns the same variable from itself about ninety times in one function (components = components.concat(...)). For each reference, TypeScript's control-flow analysis walks back over every earlier assignment, and working out each assignment's type starts another walk of the same kind. The cost per reference roughly doubles each time. The first 700 lines of that function take 15 seconds; the first 800 take 228 seconds. In the end, a single getTypeAtLocation call runs for more than ten minutes. TypeScript 5.9 behaves the same as 6.0. Branch labels are only memoised within one walk, so nothing astgen can do by reordering or caching its own queries helps. Its repeat queries are already TypeScript cache hits.

The ways to make it faster all change the output or live outside astgen: query declared types instead of narrowed ones at such sites, or fix it in TypeScript by memoising branch-label types across walks. They aren't in this PR.

…ING)

Per-file stderr line with wall ms, node count, checker call counts
(getTypeAtLocation/writeType with own ms), node-kind histogram, same-node
repeat-query count, and with ASTGEN_TYPE_TIMING_SLOW_MS=n the n slowest
individual queries. Off by default; verified byte-identical output.

Signed-off-by: Team AppThreat <cloud@appthreat.com>
One wrapper per checker method instead of three stacked ones on
getTypeAtLocation, node kinds reported by name, and counters reset by the
report. Output stays byte-identical to main (npm test, five repos and twelve
synthetic projects).

Signed-off-by: Team AppThreat <cloud@appthreat.com>
@prabhu prabhu added enhancement New feature or request js ai-auto A person set the task, and AI agents carried it through to completion labels Oct 24, 2026
@prabhu
prabhu enabled auto-merge October 24, 2026 17:07
The PR build runs npm publish --dry-run, which fails while package.json still
names the already-published 1.10.3. The AST format version stays 4.5.1: the
timing diagnostics do not change what astgen emits.

Signed-off-by: Team AppThreat <cloud@appthreat.com>
@prabhu
prabhu added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit 12bdf61 Oct 24, 2026
3 checks passed
@prabhu
prabhu deleted the perf/astgen-typegen branch October 24, 2026 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-auto A person set the task, and AI agents carried it through to completion enhancement New feature or request js

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant