[PR #751] [MERGED] .NET 8.0 and a few other perf improvements #1204

Open
opened 2026-01-29 14:51:22 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/xoofx/markdig/pull/751
Author: @MihaZupan
Created: 11/25/2023
Status: Merged
Merged: 11/25/2023
Merged by: @xoofx

Base: masterHead: net8


📝 Commits (10+)

  • 4eea9db Add .NET 8.0 target
  • 1f1364e Add SearchValues polyfill and use it in CharacterMap
  • e4f57ca Fix build warnings
  • 047c4cb Skip _lineBits read on MarkdownObject creation
  • 7803417 Rewrite CodeInline matching to make use of vectorization
  • b0bde46 Defer position calculations in LiteralInlineParser
  • c7aec82 Speed up a few character checks
  • 5cff880 Remove temporary string allocations in AutoIdentifierExtension
  • 4f1cb9d Avoid allocating strings for known emphasis character fallbacks
  • 87aa32e Optimize WriteEscape

📊 Changes

27 files changed (+576 additions, -504 deletions)

View changed files

📝 .github/workflows/ci.yml (+5 -2)
📝 src/Markdig.Tests/Markdig.Tests.csproj (+1 -1)
📝 src/Markdig.Tests/TestYamlFrontMatterExtension.cs (+3 -0)
📝 src/Markdig/Extensions/AutoIdentifiers/AutoIdentifierExtension.cs (+17 -12)
📝 src/Markdig/Helpers/BlockWrapper.cs (+1 -1)
📝 src/Markdig/Helpers/CharHelper.cs (+26 -33)
📝 src/Markdig/Helpers/CharacterMap.cs (+24 -206)
📝 src/Markdig/Helpers/FastStringWriter.cs (+3 -4)
src/Markdig/Helpers/HexConverter.cs (+27 -0)
📝 src/Markdig/Helpers/LineReader.cs (+2 -2)
📝 src/Markdig/Helpers/LinkHelper.cs (+16 -2)
📝 src/Markdig/Helpers/ObjectCache.cs (+1 -1)
📝 src/Markdig/Helpers/StringSlice.cs (+1 -1)
📝 src/Markdig/Markdig.targets (+2 -2)
📝 src/Markdig/Markdown.cs (+4 -10)
📝 src/Markdig/Parsers/Inlines/CodeInlineParser.cs (+78 -69)
📝 src/Markdig/Parsers/Inlines/LiteralInlineParser.cs (+6 -10)
src/Markdig/Polyfills/Ascii.cs (+30 -0)
src/Markdig/Polyfills/EncodingExtensions.cs (+24 -0)
src/Markdig/Polyfills/IndexOfHelpers.cs (+46 -0)

...and 7 more files

📄 Description

  • Added a .NET 8.0 TFM
  • Polyfills for a few new functionalities (Ascii, SearchValues, ContainsAnyExcept ...)
  • Replaced the CharacterMap.IndexOfOpeningCharacter implementation with a call to IndexOfAny(SearchValues)
    • Don't need manual vectorization code in Markdig for this anymore
    • Also get AVX2 paths and ARM64 acceleration "for free"
  • Changed CodeInlineParser.Match to make use of vectorized helpers
  • Sped up WriteEscape & WriteEscapeUrl rendering (vectorized scanning via SearchValues)
  • A few random alloc / codegen improvements

A few rough numbers from parsing a large markdown document with precise source locations (.NET 8 perf improvements blogpost).
Both main and pr numbers are from 8.0

Method Job Mean Error Ratio
Parse main 2,762.2 us 13.73 us 1.00
Parse pr 2,509.3 us 13.97 us 0.91
ParseAdvanced main 7,991.8 us 49.89 us 1.00
ParseAdvanced pr 7,758.2 us 48.96 us 0.97
Render main 954.6 us 3.39 us 1.00
Render pr 710.6 us 2.42 us 0.74
RenderAdvanced main 1,301.3 us 4.76 us 1.00
RenderAdvanced pr 1,068.6 us 20.04 us 0.82
Including 7.0 vs 8.0 comparison
Method Job Runtime Mean Error Ratio
Parse main .NET 7.0 3,125.7 us 18.30 us 1.00
Parse pr .NET 8.0 2,486.9 us 9.08 us 0.80
ParseAdvanced main .NET 7.0 8,481.4 us 35.35 us 1.00
ParseAdvanced pr .NET 8.0 7,682.9 us 17.01 us 0.91
Render main .NET 7.0 1,140.1 us 4.04 us 1.00
Render pr .NET 8.0 711.8 us 1.49 us 0.62
RenderAdvanced main .NET 7.0 1,548.4 us 5.30 us 1.00
RenderAdvanced pr .NET 8.0 1,047.4 us 4.44 us 0.68

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/xoofx/markdig/pull/751 **Author:** [@MihaZupan](https://github.com/MihaZupan) **Created:** 11/25/2023 **Status:** ✅ Merged **Merged:** 11/25/2023 **Merged by:** [@xoofx](https://github.com/xoofx) **Base:** `master` ← **Head:** `net8` --- ### 📝 Commits (10+) - [`4eea9db`](https://github.com/xoofx/markdig/commit/4eea9db35c30421599a04be36adb61e6d6e038fa) Add .NET 8.0 target - [`1f1364e`](https://github.com/xoofx/markdig/commit/1f1364e69b094894bd50a478fc9e5edf124ab0d2) Add SearchValues polyfill and use it in CharacterMap - [`e4f57ca`](https://github.com/xoofx/markdig/commit/e4f57ca21e58e00698bb3c7294198f844b00ca29) Fix build warnings - [`047c4cb`](https://github.com/xoofx/markdig/commit/047c4cbcbbb8dc5af93fb56465f7f8664d8c0464) Skip _lineBits read on MarkdownObject creation - [`7803417`](https://github.com/xoofx/markdig/commit/7803417e5cd5d2110c4a1b04df3b861100cda111) Rewrite CodeInline matching to make use of vectorization - [`b0bde46`](https://github.com/xoofx/markdig/commit/b0bde46cc1017fa02669a77f7abd0fb862fa3844) Defer position calculations in LiteralInlineParser - [`c7aec82`](https://github.com/xoofx/markdig/commit/c7aec822b073f463bf9e4b05cae3781051bd580a) Speed up a few character checks - [`5cff880`](https://github.com/xoofx/markdig/commit/5cff880c9037d72b2a8833577aaf889d1d2073e9) Remove temporary string allocations in AutoIdentifierExtension - [`4f1cb9d`](https://github.com/xoofx/markdig/commit/4f1cb9da0836f7b21c516910b98cc22b1ac3b286) Avoid allocating strings for known emphasis character fallbacks - [`87aa32e`](https://github.com/xoofx/markdig/commit/87aa32e1bd2abe174729e63039fa31bc94b892d2) Optimize WriteEscape ### 📊 Changes **27 files changed** (+576 additions, -504 deletions) <details> <summary>View changed files</summary> 📝 `.github/workflows/ci.yml` (+5 -2) 📝 `src/Markdig.Tests/Markdig.Tests.csproj` (+1 -1) 📝 `src/Markdig.Tests/TestYamlFrontMatterExtension.cs` (+3 -0) 📝 `src/Markdig/Extensions/AutoIdentifiers/AutoIdentifierExtension.cs` (+17 -12) 📝 `src/Markdig/Helpers/BlockWrapper.cs` (+1 -1) 📝 `src/Markdig/Helpers/CharHelper.cs` (+26 -33) 📝 `src/Markdig/Helpers/CharacterMap.cs` (+24 -206) 📝 `src/Markdig/Helpers/FastStringWriter.cs` (+3 -4) ➕ `src/Markdig/Helpers/HexConverter.cs` (+27 -0) 📝 `src/Markdig/Helpers/LineReader.cs` (+2 -2) 📝 `src/Markdig/Helpers/LinkHelper.cs` (+16 -2) 📝 `src/Markdig/Helpers/ObjectCache.cs` (+1 -1) 📝 `src/Markdig/Helpers/StringSlice.cs` (+1 -1) 📝 `src/Markdig/Markdig.targets` (+2 -2) 📝 `src/Markdig/Markdown.cs` (+4 -10) 📝 `src/Markdig/Parsers/Inlines/CodeInlineParser.cs` (+78 -69) 📝 `src/Markdig/Parsers/Inlines/LiteralInlineParser.cs` (+6 -10) ➕ `src/Markdig/Polyfills/Ascii.cs` (+30 -0) ➕ `src/Markdig/Polyfills/EncodingExtensions.cs` (+24 -0) ➕ `src/Markdig/Polyfills/IndexOfHelpers.cs` (+46 -0) _...and 7 more files_ </details> ### 📄 Description - Added a .NET 8.0 TFM - Polyfills for a few new functionalities (`Ascii`, `SearchValues`, `ContainsAnyExcept` ...) - Replaced the `CharacterMap.IndexOfOpeningCharacter` implementation with a call to `IndexOfAny(SearchValues)` - Don't need manual vectorization code in Markdig for this anymore - Also get AVX2 paths and ARM64 acceleration "for free" - Changed `CodeInlineParser.Match` to make use of vectorized helpers - Sped up `WriteEscape` & `WriteEscapeUrl` rendering (vectorized scanning via SearchValues) - A few random alloc / codegen improvements A few rough numbers from parsing a large markdown document with precise source locations (.NET 8 perf improvements blogpost). Both `main` and `pr` numbers are from 8.0 | Method | Job | Mean | Error | Ratio | |--------------- |----- |-----------:|---------:|------:| | Parse | main | 2,762.2 us | 13.73 us | 1.00 | | Parse | pr | 2,509.3 us | 13.97 us | 0.91 | | | | | | | | ParseAdvanced | main | 7,991.8 us | 49.89 us | 1.00 | | ParseAdvanced | pr | 7,758.2 us | 48.96 us | 0.97 | | | | | | | | Render | main | 954.6 us | 3.39 us | 1.00 | | Render | pr | 710.6 us | 2.42 us | 0.74 | | | | | | | | RenderAdvanced | main | 1,301.3 us | 4.76 us | 1.00 | | RenderAdvanced | pr | 1,068.6 us | 20.04 us | 0.82 | <details> <summary>Including 7.0 vs 8.0 comparison</summary> | Method | Job | Runtime | Mean | Error | Ratio | |--------------- |----- |--------- |-----------:|---------:|------:| | Parse | main | .NET 7.0 | 3,125.7 us | 18.30 us | 1.00 | | Parse | pr | .NET 8.0 | 2,486.9 us | 9.08 us | 0.80 | | | | | | | | | ParseAdvanced | main | .NET 7.0 | 8,481.4 us | 35.35 us | 1.00 | | ParseAdvanced | pr | .NET 8.0 | 7,682.9 us | 17.01 us | 0.91 | | | | | | | | | Render | main | .NET 7.0 | 1,140.1 us | 4.04 us | 1.00 | | Render | pr | .NET 8.0 | 711.8 us | 1.49 us | 0.62 | | | | | | | | | RenderAdvanced | main | .NET 7.0 | 1,548.4 us | 5.30 us | 1.00 | | RenderAdvanced | pr | .NET 8.0 | 1,047.4 us | 4.44 us | 0.68 | </details> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-29 14:51:22 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/markdig#1204