Skip to content

perf: MD outline ~15x + full Inline fast path (~2.3x) - #145

Draft
tiensonqin wants to merge 7 commits into
masterfrom
logseq/parser-perf-10x-c55d
Draft

perf: MD outline ~15x + full Inline fast path (~2.3x)#145
tiensonqin wants to merge 7 commits into
masterfrom
logseq/parser-perf-10x-c55d

Conversation

@tiensonqin

@tiensonqin tiensonqin commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Optimize logseq/mldoc Markdown parsing for the Logseq hot path (outline-first, then full).

Performance (1.2MB examples/logseq_large.md, 3-iter avg, same machine)

Mode master this branch speedup
parse_outline_only 0.354s 0.020s ~17.5×
Full Markdown 0.479s 0.061s ~7.9×

Approach

  • Research: Evaluated Parseff (OCaml 5.3+ effects). Faster on JSON/CSV-style benches, but slower than Angstrom on short Logseq inline titles (look_ahead + effects). Not adopted; algorithmic cuts matter more here.
  • parse_outline_only: Skip heavy nested inline once block type is known (existing flag). Outline keeps tags / [[page]] / ((block)) only (drops emphasis, etc.).
  • Md_outline: Line-oriented MD document parser (no Angstrom block choice backtracking). Used for outline and full Markdown.
  • Full mode extras: Inline.parse, fenced Src (language/options/pos_meta), latex env, quote continuation, heading anchors.
  • Inline fast path: Pure-OCaml try_fast_md_inline for plain/tag/page/block refs.

Tests

dune runtest green (markdown, outline markdown, org, zip, export-md, export-opml).

Cloud Agent env

OCaml 5.3 + Node 22 install script proposed (draft build bld-20260829-0c025de9-… verified). Save the environment in the Cursor dashboard to persist it.

Not in this PR

  • _opam/ local switch (untracked)
  • Generated examples/logseq_large.md (bench fixture)

Test plan

  • dune runtest
  • dune exec ./bench/time_parse.exe vs master
  • Fresh Cloud Agent build verification (ocaml/node/dune)
  • Logseq integration smoke (outline load + full parse)
Open in Web Open in Cursor 

Outline mode now extracts only node refs, tags, and properties:
- Fast direct scanner for #tag / [[page]] / ((block))
- Markdown-specific outline parser with peek dispatch
- Skip front-matter probing and position tracking on outline path
- Lighter heading title lookahead and outline inline pre-checks

Also adds bench/time_parse.exe for Logseq-sized Markdown fixtures.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
@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.

cursoragent and others added 2 commits August 29, 2026 09:32
Replace Angstrom block choice for MD outline with a dedicated line
scanner (headings, properties, lists, quotes, fences, footnotes) while
keeping Outline_inline for refs/tags. Fixes parse_md_outline empty-title
edge cases via the new path. ~0.026s vs ~0.30s master on 1.2MB fixture.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
@cursor cursor Bot changed the title perf: outline_only Markdown ~2.2x + structure for further gains perf: Markdown outline_only ~12x via line-oriented parser Aug 29, 2026
Tried Parseff (OCaml 5.3 effects) for MD Inline: ~4x slower than
Angstrom on short Logseq titles (effects/look_ahead overhead), so not
adopted.

Instead add a pure-OCaml MD Inline fast path (plain/#tag/[[page]]/
((block))) with Angstrom fallback. Full parse ~0.19s vs ~0.43s master
(~2.3x) on the 1.2MB fixture; outline stays ~15x.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
@cursor cursor Bot changed the title perf: Markdown outline_only ~12x via line-oriented parser perf: MD outline ~15x + full Inline fast path (~2.3x) Aug 29, 2026
cursoragent and others added 3 commits August 29, 2026 10:08
Route all Markdown (outline and full) through the line scanner. Full mode
uses Inline.parse, Src fences with options/pos_meta, latex env, quote
continuation, and heading anchors — ~7–9× vs master on logseq_large while
keeping outline_only ~15×.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
The generative MD fixture builder omitted the size field after it was
added to Type.Heading, which broke dune builds of that test helper.

Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
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.

3 participants