Skip to content

perf: MD parse_outline_only ~1.7× vs master (post #145) - #147

Closed
tiensonqin wants to merge 4 commits into
masterfrom
logseq/outline-perf-5x-a697
Closed

perf: MD parse_outline_only ~1.7× vs master (post #145)#147
tiensonqin wants to merge 4 commits into
masterfrom
logseq/outline-perf-5x-a697

Conversation

@tiensonqin

@tiensonqin tiensonqin commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Further speed up Markdown parse_outline_only on top of #145. Changes stay in md_outline.ml / outline_inline.ml (no second document parser, no Parseff, no logseq/logseq bump).

Performance (1.2MB examples/logseq_large.md, 3-iter avg, same machine, dune exec --profile=release ./bench/time_parse.exe)

Mode master (02d6fa1) this branch speedup
parse_outline_only 0.0233s (0.0231 / 0.0235) 0.0137s (0.0135 / 0.0139) ~1.7×
Full Markdown 0.0578s 0.0526s ~1.1× (not a goal)

Target was ~5× (~0.0047s). That is past the AST floor on this file: outline emits 24 432 blocks. Newline indexing alone is ~0.002s; building those nodes plus interned title inlines is the rest. Previous estimate of a ~2.9× construction floor (~0.008s) still looks right; 5× would require a smaller or lazier AST.

Approach

  • Iterative page/block-ref scans (no per-char recursion); depth-capped nested [[a [[b]]]] in the fast path
  • First-char dispatch; cheap block-boundary checks (no full heading / Inline.parse just to classify)
  • Outline property refs via the outline scanner, not full Inline.parse
  • Intern repeated [[page]] / #tag / ((block)) nodes and common heading records within one parse (structural = unchanged)
  • Outline indexes newlines and parses headings from source spans so most lines are never copied
  • Stack caps: nested lists 64, nested page-ref AST 32
  • Escaped refs such as [[\]]] still fall back to Angstrom

Tests

  • dune runtest (markdown, outline markdown, org, zip, export-md, export-opml)
  • dune exec ./bench/time_parse.exe vs master, same machine, multiple runs

Full parse keeps the existing line-array path (shared cheap classifiers only).

Open in Web Open in Cursor 

cursoragent and others added 2 commits August 30, 2026 05:22
Convert page/block-ref and markup scans to while-loops so a long
unmatched [[ cannot blow the stack. Build Nested_link in the fast
path (depth-capped) instead of falling back to Angstrom, and skip
the extra backslash pre-pass.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Classify lines by first non-space char instead of trying every
constructor. Boundary checks no longer fully parse headings or run
Inline.parse. Outline properties use the outline inline scanner,
titles are scanned in-place, line_starts is skipped, and list/ref
recursion is capped.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Copilot AI lite review requested due to automatic review settings August 30, 2026 05:31
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

cursoragent and others added 2 commits August 30, 2026 05:33
[[\]]] must still parse as Page_ref "]" — any backslash in the
scan range disables the fast path (iterative check, not recursive).

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Reuse page/tag/block-ref nodes and common heading records within a
parse. Outline mode indexes newlines and classifies/parses headings
from source spans so most lines are never copied into strings.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
@cursor cursor Bot changed the title perf: speed up MD parse_outline_only (~first-char dispatch, less alloc) perf: MD parse_outline_only ~1.7× vs master (post #145) Aug 30, 2026
@tiensonqin tiensonqin closed this Aug 30, 2026
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.

4 participants