Skip to content

perf: add fast path and cached pipeline to StripMarkdown - #3838

Open
Mpdreamz wants to merge 1 commit into
mainfrom
perf/strip-markdown-fast-path
Open

perf: add fast path and cached pipeline to StripMarkdown#3838
Mpdreamz wants to merge 1 commit into
mainfrom
perf/strip-markdown-fast-path

Conversation

@Mpdreamz

Copy link
Copy Markdown
Member

Summary

Markdig.Markdown.ToPlainText(string, TextWriter) with no pipeline builds a fresh MarkdownPipeline + renderer on every call. MarkdownFile.cs calls StripMarkdown 2–5 times per file:

  • constructor sets Title = RelativePath (a plain path string)
  • ReadDocumentInstructions reassigns Title and NavigationTitle
  • once per h2+ heading in GetAnchors

Two changes:

  1. Cached pipeline — a static MarkdownPipeline shared across calls eliminates the repeated MarkdownPipelineBuilder.Build() cost.
  2. Fast path — a SearchValues<char> check skips the StringWriter + Markdig entirely for strings that contain no markdown-syntax characters. Titles are overwhelmingly plain text (including the RelativePath seed assignment in the constructor).

Test plan

  • dotnet test tests/Elastic.Markdown.Tests/ --filter StripMarkdown|DropdownPlainText — 16 tests pass
  • dotnet test tests/Elastic.Markdown.Tests/ — full 1960-test suite passes (9 new tests in Helpers/StripMarkdownTests.cs)
  • dotnet run --project src/tooling/docs-migrate -- bench — record ResolveDirectoryTree time

🤖 Generated with Claude Code

Markdig.Markdown.ToPlainText(string, TextWriter) with no pipeline
argument builds a fresh MarkdownPipeline + renderer on every call.
MarkdownFile.cs calls StripMarkdown 2-5 times per file (ctor sets
Title = RelativePath, ReadDocumentInstructions reassigns Title and
NavigationTitle, plus once per h2+ heading), so the overhead compounds
across 435k files.

Two changes:
1. Cache a shared plain-text MarkdownPipeline — eliminates the repeated
   MarkdownPipelineBuilder.Build() cost for every call that does reach
   Markdig.
2. Add a fast path using SearchValues<char>: titles are overwhelmingly
   plain text (including the RelativePath seed assignment), so skip the
   StringWriter + Markdig entirely when no markdown-syntax character is
   present in the input string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant