perf(#3182): linear JS/TS func_start start anchor on blank runs (nx wall -73%) - #3335
Merged
Merged
Conversation
…all -73%) The assignment branch of javascript/typescript func_start started with `(?:^|(?<=[^<>(,\s]))[ \t\n]*` under re.M. `_build_brace_safe_stream` blanks a multi-line template literal to same-length whitespace, and the bare `^` fired on every line of that blank run; each attempt's `[ \t\n]*` scanned to the run's end before failing -- quadratic in the run. nx's lock-file fixtures (one 16k-line template each) cost 13-60s apiece in Cartography_Mode_B_Braces, the worst hitting the 60s fuse. Inside a whitespace run `\b` can only hold at the run's end, so every start in one run shares one outcome. `^` is now taken only on a non-blank line, on a blank run's first line start (previous line ends in a non-space), or at the file start -- three mutually exclusive anchors, so a failed continuation is never re-run through a second one. nx, phase_ab 2 rounds + A-vs-A control (control <1% on wall/Optical): wall 70.8s -> 19.4s (-72.6%); 5_Optical_Detector 320.5s -> 70.5s (-78.0%); Cartography_Mode_B 90.5s -> 21.1s. audit.json + sarif identical; every function_data row (name, start_line, loc, complexity, args) identical. vscode: Cartography_Mode_B -4.3% (control 0.0%), wall within noise, identical. Match-set parity on 58 JS/TS repos (~245k files, raw + brace-safe streams): identical except 21 matches in 20 files whose OLD start sat on a blank line after a line ending `<>(,` + trailing blanked text; those now start on the declaration's own line (same end, same groups). Golden crucible (full) passes unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Closed
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #3182. Next fleet hotspot after #3317:
typescript::Cartography_Mode_B_Braces(539s fleet CPU in v2.9.1), led by nx at 90 s/MLOC versus ~10 for grafana/sentry.Root cause
The assignment branch of JS/TS
func_startbegan(?:^|(?<=[^<>(,\s]))[ \t\n]*underre.M._build_brace_safe_streamblanks a multi-line template literal to same-length whitespace, and the bare^fired on every line of the blank run. Each attempt scanned to the run's end before failing, which is quadratic: 4× per doubling, about 5.5s for 4,000 blank lines. nx'slock-file/__fixtures__/*.tsfiles (one 16k-line template each) cost 13–60s apiece, and the worst hit the 60s fuse. A sweep of every language's rules found this shape only in JS and TSfunc_startat fleet-relevant cost.Fix
Inside a whitespace run,
\bcan only hold at the run's end, so every start in one run gives the same result.^is now taken only:These anchors are mutually exclusive. An earlier non-exclusive draft re-ran the failed continuation through a second anchor and was slower on a 1.3MB single-line file.
Evidence
audit.jsonandsarifare identical on both repos. On nx, everyfunction_datarow (name, start_line, loc, complexity, args) is also identical.<>(,plus trailing blanked text (a string or comment). The new match starts on the declaration's own line, with the same end and the same groups. Every one was machine-checked for that shape. This is a small line-attribution improvement: the old start sat 1–7 lines early..gitgalaxydependency cache and pass warm, so that flake is pre-existing and environmental.New test
tests/extraction/languages/test_func_start_blank_run_3182.py:Not in scope
runtime'sTCFullEndElement.cs/MathF.cs, ~20s each): the stacked-[InlineData]bracket ambiguity, already tracked as perf: csharp func_start exponential backtracking on adjacent [...] (still fuses a roslyn file → 0 functions) #3320 (waits on the py3.11 floor, Raise minimum Python from 3.9 to 3.11 #3322).TypeScript/tests/cases/fourslash/codeFixClassImplementInterfaceNoTruncationProperties.ts(45s on main and on this branch). A 1.3MB blanked single line where branch 1's{0,200}annotation loop × lookahead whitespace scan is O(200·run). It's one file in the fleet, so I left it as-is.🤖 Generated with Claude Code