perf(checker): fast-path compareNodes for identical AST parent containers and use cmp.Compare - #64551
HazyLab (hazyhaar) wants to merge 1 commit into
Conversation
|
This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
GC tuning affects long-lived modes, symbol IDs can collide after wraparound, and oracle tests depend on machine-local paths.
Review effort: Balanced
Findings: 1
Open (4)
What changed in this PR
Adds GC, SIMD scanning, and symbol-layout optimizations to the native TypeScript compiler.
Changes:
- Defaults GC tuning to
GOGC=400. - Adds SIMD kernels and parity benchmarks for scanning and UTF-16 operations.
- Compacts symbol IDs and reserves space for atom IDs.
| File | Description |
|---|---|
tsc/cmd/tsc/main.go |
Applies GC tuning at startup. |
tsc/internal/core/gctuning.go |
Defines GC tuning behavior. |
tsc/internal/core/gctuning_test.go |
Tests GC configuration. |
tsc/internal/core/core.go |
Uses accelerated line and UTF-16 kernels. |
tsc/internal/core/vectorkernels_simd.go |
Enables SIMD kernels on supported builds. |
tsc/internal/core/vectorkernels_nosimd.go |
Disables SIMD kernels elsewhere. |
tsc/internal/core/tsgo_lines_gen.go |
Implements AVX2 line scanning. |
tsc/internal/core/tsgo_lines_nosimd_gen.go |
Provides scalar line scanning. |
tsc/internal/core/tsgo_utf16_gen.go |
Implements AVX2 UTF-16 counting. |
tsc/internal/core/tsgo_utf16_nosimd_gen.go |
Provides scalar UTF-16 counting. |
tsc/internal/core/tsgo_parity_test.go |
Adds kernel parity tests. |
tsc/internal/core/tsgo_bench_test.go |
Adds core benchmarks. |
tsc/internal/scanner/scanner.go |
Accelerates comment scanning. |
tsc/internal/scanner/tsgo_skip_gen.go |
Implements AVX2 comment skipping. |
tsc/internal/scanner/tsgo_skip_nosimd_gen.go |
Provides scalar comment skipping. |
tsc/internal/scanner/tsgo_skip_parity_test.go |
Adds scanner parity tests. |
tsc/internal/scanner/tsgo_skip_bench_test.go |
Adds scanner benchmark. |
tsc/internal/ast/ids.go |
Narrows symbol IDs to 32 bits. |
tsc/internal/ast/utilities.go |
Narrows the global symbol counter. |
tsc/internal/ast/symbol.go |
Compacts symbol storage and adds AtomId. |
tsc/internal/ast/symbol_size_test.go |
Verifies symbol layout. |
Files not reviewed (6)
- tsc/internal/core/tsgo_lines_gen.go: Generated file
- tsc/internal/core/tsgo_lines_nosimd_gen.go: Generated file
- tsc/internal/core/tsgo_utf16_gen.go: Generated file
- tsc/internal/core/tsgo_utf16_nosimd_gen.go: Generated file
- tsc/internal/scanner/tsgo_skip_gen.go: Generated file
- tsc/internal/scanner/tsgo_skip_nosimd_gen.go: Generated file
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| var ( | ||
| nextNodeId atomic.Uint64 | ||
| nextSymbolId atomic.Uint64 | ||
| nextSymbolId atomic.Uint32 |
There was a problem hiding this comment.
It's actually very possible that long running servers wrap around
|
|
||
| func runMain() int { | ||
| core.ApplyDebugStackLimit() | ||
| core.ApplyGCTuning() |
| tsgoLinesSource = "/devhoros/c2simd/sources/tsgo/tsgo_lines.c" | ||
| tsgoUTF16Source = "/devhoros/c2simd/sources/tsgo/tsgo_utf16.c" |
|
|
||
| // tsgoSkipSource is the C source the tsgo_skip*_gen.go files are transpiled | ||
| // from by sgoiter; the gcc oracle below compiles it unchanged. | ||
| const tsgoSkipSource = "/devhoros/c2simd/sources/tsgo/tsgo_skip.c" |
|
@microsoft-github-policy-service agree |
bfa8c16 to
b4e6d60
Compare
|
This PR contains totally unrelated changes. If we want any of this they'd have to be split into different PRs. Turning up GOGC is also going to really increase the memory footprint. |
…rs and use cmp.Compare Fast-path compareNodes when two AST nodes share the same direct parent container (n1.Parent == n2.Parent), avoiding full AST traversals to root SourceFiles while preserving identical Pos() ordering. Use cmp.Compare for 64-bit SymbolId fallback comparison in compareSymbolsWorker to avoid potential integer overflow.
b4e6d60 to
407a692
Compare
|
Agreed, thanks for the review. This PR mixed three unrelated changes. I have reduced this PR to the checker optimization only:
Regarding your other points:
The branch has been updated to reflect only this minimal checker change. |
|
The PR description is still describing the original state. |
|
TypeScript Bot (@typescript-bot) perf test this |
|
Daniel Rosenwasser (@DanielRosenwasser), the perf run you requested failed. You can check the log here. |
|
|
|
TypeScript Bot (@typescript-bot) perf test this |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
lspComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
startupComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
This seems well and good, but I also wonder if we could check more parents safely, even see if any of the two levels are the same or something. I bet there's a tradeoff of extra parent checks saving comparisons and not. Or, we should do some sort of more clever parent thing generally because |



Description
This PR introduces two focused optimizations in
tsc/internal/checker/utilities.go:Fast-path in
compareNodesfor identical parent containers:n1.Parent != nil && n1.Parent == n2.Parent), they are guaranteed to reside in the exact sameSourceFile.n1.Pos() - n2.Pos(), entirely eliding the full AST ancestry traversal to rootSourceFilenodes (ast.GetSourceFileOfNode) and the subsequent file index map lookups.64-bit integer overflow protection in
compareSymbolsWorker:int(ast.GetSymbolId(s1)) - int(ast.GetSymbolId(s2))withcmp.Compare(ast.GetSymbolId(s1), ast.GetSymbolId(s2))for the uniqueSymbolIdfallback comparison.uint64identifier without narrowing, eliminating any potential overflow risks.Validation & Test Results
go test -race -count=1 ./tsc/internal/checker/...-> PASSTestLocal) verified bit-exact with 0 regressions and 0 data races.