[PR #396] [MERGED] Use BitVector128 in CharacterMap<T> #989

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

📋 Pull Request Information

Original PR: https://github.com/xoofx/markdig/pull/396
Author: @KrisVandermotten
Created: 2/4/2020
Status: Merged
Merged: 2/6/2020
Merged by: @xoofx

Base: masterHead: CharacterMapBitVector128


📝 Commits (2)

  • 525e2c7 Use BitVector128 in CharacterMap
  • 9321628 Use uint instead of ulong

📊 Changes

1 file changed (+33 additions, -10 deletions)

View changed files

📝 src/Markdig/Helpers/CharacterMap.cs (+33 -10)

📄 Description

CharacterMap<T> uses a bool[] isOpeningCharacter for quick lookup.

This PR replaces that by a custom BitVector128 that stores 128 bits is two ulong fields using a fixed size buffer.

This results in a measurable speedup:

The benchmark:

public class Program
{
    private string text = File.ReadAllText("spec.md");

    [Benchmark]
    public void TestMarkdig()
    {
        Markdown.Parse(text);
    }

    private static void Main()
    {
        BenchmarkRunner.Run<Program>();
    }
}

The results on .NET Framework:

BenchmarkDotNet=v0.10.6, OS=Windows 10.0.18363
Processor=Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), ProcessorCount=8
Frequency=10000000 Hz, Resolution=100.0000 ns, Timer=UNKNOWN
  [Host]     : Clr 4.0.30319.42000, 64bit RyuJIT-v4.8.4075.0
  DefaultJob : Clr 4.0.30319.42000, 64bit RyuJIT-v4.8.4075.0

Before:

Method Mean Error StdDev
TestMarkdig 3.363 ms 0.0209 ms 0.0196 ms

After:

Method Mean Error StdDev
TestMarkdig 3.275 ms 0.0220 ms 0.0206 ms

The results on .NET Core:

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.101
  [Host]     : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT
  DefaultJob : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT

Before:

Method Mean Error StdDev
TestMarkdig 3.128 ms 0.0207 ms 0.0193 ms

After:

Method Mean Error StdDev
TestMarkdig 3.034 ms 0.0173 ms 0.0145 ms

Conclusion: parsing time is reduced by about 3 %.


🔄 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/396 **Author:** [@KrisVandermotten](https://github.com/KrisVandermotten) **Created:** 2/4/2020 **Status:** ✅ Merged **Merged:** 2/6/2020 **Merged by:** [@xoofx](https://github.com/xoofx) **Base:** `master` ← **Head:** `CharacterMapBitVector128` --- ### 📝 Commits (2) - [`525e2c7`](https://github.com/xoofx/markdig/commit/525e2c7fb893d222ff22568aafc5c5c3a2935d7c) Use BitVector128 in CharacterMap<T> - [`9321628`](https://github.com/xoofx/markdig/commit/9321628b9c53a2179d509ed5c588836af720281a) Use uint instead of ulong ### 📊 Changes **1 file changed** (+33 additions, -10 deletions) <details> <summary>View changed files</summary> 📝 `src/Markdig/Helpers/CharacterMap.cs` (+33 -10) </details> ### 📄 Description `CharacterMap<T>` uses a `bool[] isOpeningCharacter` for quick lookup. This PR replaces that by a custom `BitVector128` that stores 128 bits is two ulong fields using a fixed size buffer. This results in a measurable speedup: The benchmark: public class Program { private string text = File.ReadAllText("spec.md"); [Benchmark] public void TestMarkdig() { Markdown.Parse(text); } private static void Main() { BenchmarkRunner.Run<Program>(); } } The results on .NET Framework: BenchmarkDotNet=v0.10.6, OS=Windows 10.0.18363 Processor=Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), ProcessorCount=8 Frequency=10000000 Hz, Resolution=100.0000 ns, Timer=UNKNOWN [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.8.4075.0 DefaultJob : Clr 4.0.30319.42000, 64bit RyuJIT-v4.8.4075.0 Before: | Method | Mean | Error | StdDev | |------------ |---------:|----------:|----------:| | TestMarkdig | 3.363 ms | 0.0209 ms | 0.0196 ms | After: | Method | Mean | Error | StdDev | |------------ |---------:|----------:|----------:| | TestMarkdig | 3.275 ms | 0.0220 ms | 0.0206 ms | The results on .NET Core: BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=3.1.101 [Host] : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT DefaultJob : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT Before: | Method | Mean | Error | StdDev | |------------ |---------:|----------:|----------:| | TestMarkdig | 3.128 ms | 0.0207 ms | 0.0193 ms | After: | Method | Mean | Error | StdDev | |------------ |---------:|----------:|----------:| | TestMarkdig | 3.034 ms | 0.0173 ms | 0.0145 ms | Conclusion: parsing time is reduced by about 3 %. --- <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:48:13 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/markdig#989