From 2989b178e1bf5b51a228c8d93479188150dcc56b Mon Sep 17 00:00:00 2001 From: Michael Han <107991372+shimmyshimmer@users.noreply.github.com> Date: Tue, 28 Jul 2026 05:47:48 -0700 Subject: [PATCH] perf(studio): remove quadratic region scan in LaTeX preprocessing (#7538) findCodeBlockRegions scanned every region found so far for each inline code match, and accepted inline spans were appended to the same array, making it quadratic in the number of inline spans. preprocessLaTeX runs on the full message text every animation frame while streaming and calls it twice. Fenced and inline matches are both ascending and non-overlapping, so walk the fenced list with a cursor instead. Only fenced regions can contain an inline span, so previously accepted inline regions never needed checking. 34,670 chars with 2,100 inline spans: 5.51ms per call to 0.12ms. Co-authored-by: shimmyshimmer --- studio/frontend/src/lib/latex.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/studio/frontend/src/lib/latex.ts b/studio/frontend/src/lib/latex.ts index edf9875602..ccccccbbe4 100644 --- a/studio/frontend/src/lib/latex.ts +++ b/studio/frontend/src/lib/latex.ts @@ -33,19 +33,20 @@ function findCodeBlockRegions(content: string): Array<[number, number]> { regions.push([match.index, match.index + match[0].length]); } - // Inline code: `...` (skip spans inside fenced blocks, filtered below) + // Inline code: `...`, skipped when inside a fenced block. Both loops yield + // ascending matches, so walk the fenced list with a cursor rather than + // rescanning it per match (was quadratic on code-heavy text). + const fencedCount = regions.length; const inlineRe = /`[^`\n]+`/g; + let fencedIndex = 0; while ((match = inlineRe.exec(content)) !== null) { const start = match.index; const end = start + match[0].length; - let inside = false; - for (const [rs, re] of regions) { - if (start >= rs && end <= re) { - inside = true; - break; - } + while (fencedIndex < fencedCount && regions[fencedIndex][1] <= start) { + fencedIndex += 1; } - if (!inside) { + const fenced = fencedIndex < fencedCount ? regions[fencedIndex] : null; + if (!(fenced && start >= fenced[0] && end <= fenced[1])) { regions.push([start, end]); } }