Skip to content

perf(rust): restore math spans in one pass instead of rescanning per token - #948

Merged
PathGao merged 1 commit into
masterfrom
perf/render
Oct 1, 2026
Merged

PathGao merged 1 commit into
masterfrom
perf/render

Conversation

@PathGao

@PathGao PathGao commented Oct 1, 2026

Copy link
Copy Markdown
Collaborator

What this is

restore_math_spans searched the rest of the HTML for both token spellings on every math token. The lowercase heading-anchor spelling is usually absent, so each search ran to the end of the document: tokens × document length. It now remembers where each spelling next occurs and searches again only once the cursor has passed it.

Mechanism

convert_markdown on a 1.6 MB sample built from samples/, release: 3.31 s → 122 ms, of which restore_math_spans 2.99 s → 2.5 ms. Doubling the sample took it from 3.0 s to 11.6 s before, so it was quadratic. Only the samples with math showed it.

Tests

math_tokens_in_headings_and_text_restore_in_order interleaves heading and body math and checks both anchor ids and the order of all five spans. It passes on the old code too: the output did not change. It guards the cursor bookkeeping.

Verification

  • 29 renders (samples/*.md, their 2× and 4× copies, the 1.6 MB sample and its 2×) with the old code and the new: diff -r is empty
  • cargo fmt --check, cargo clippy --all-targets -- -D warnings: clean
  • cargo test: 186 passed

Not verified: the app itself. encoding-gbk-large is still superlinear inside comrak (80 ms at 2×, 311 ms at 4×), which this does not touch.

…token

restore_math_spans searched the rest of the HTML for both token spellings
on every token. The lowercase heading-anchor spelling is usually absent, so
each search ran to the end of the document: quadratic in the number of math
spans. Cache the next position of each spelling and search again only once
it has been passed.

convert_markdown on a 1.6 MB concatenation of samples/*.md (release):
restore pass 2.3-3.0 s -> 2.5 ms, total 2.7-3.3 s -> 122 ms.

Rendered every samples/*.md, their 2x/4x copies and the 1.6 MB file before
and after: all 29 outputs byte-identical.
@PathGao
PathGao merged commit 04fc578 into master Oct 1, 2026
3 of 4 checks passed
@PathGao
PathGao deleted the perf/render branch October 1, 2026 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant