From 7f498a2e07fc4098cf0e2cd0996130848a8bf8df Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Tue, 3 Feb 2026 08:51:25 +0000 Subject: [PATCH] chore: improve markdown to html perf (#26644) ### What does this PR do? I was looking at the [recent support](https://github.com/oven-sh/bun/pull/26440) for markdown and did some benchmarking against [bindings](https://github.com/just-js/lo/blob/main/lib/md4c/api.js) i created for my `lo` runtime to `md4c`. In some cases, Bun is quite a bit slower, so i did a bit of digging and came up with this change. It uses `indexOfAny` which should utilise `SIMD` where it's available to scan ahead in the payload for characters that need escaping. In [benchmarks](https://gist.github.com/billywhizz/397f7929a8920c826c072139b695bb68#file-results-md) I have done this results in anywhere from `3%` to `~15%` improvement in throughput. The bigger the payload and the more space between entities the bigger the gain afaict, which would make sense. ### How did you verify your code works? It passes `test/js/bun/md/*.test.ts` running locally. Only tested on macos. Can test on linux but I assume that will happen in CI anyway? ## main ![bun-main](https://github.com/user-attachments/assets/8b173b34-1f20-4e52-bb67-bb8b7e5658f3) ## patched ![bun-patch](https://github.com/user-attachments/assets/26bb600c-234c-4903-8f70-32f167481156) --- src/md/html_renderer.zig | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/md/html_renderer.zig b/src/md/html_renderer.zig index 016f8ce94f..afeb22a05e 100644 --- a/src/md/html_renderer.zig +++ b/src/md/html_renderer.zig @@ -486,22 +486,27 @@ pub const HtmlRenderer = struct { } pub fn writeHtmlEscaped(self: *HtmlRenderer, txt: []const u8) void { - var start: usize = 0; - for (txt, 0..) |c, i| { - const replacement: ?[]const u8 = switch (c) { - '&' => "&", - '<' => "<", - '>' => ">", - '"' => """, - else => null, + var i: usize = 0; + const needle = "&<>\""; + + while (true) { + const next = std.mem.indexOfAny(u8, txt[i..], needle) orelse { + self.write(txt[i..]); + return; }; - if (replacement) |r| { - if (i > start) self.write(txt[start..i]); - self.write(r); - start = i + 1; + const pos = i + next; + if (pos > i) + self.write(txt[i..pos]); + const c = txt[pos]; + switch (c) { + '&' => self.write("&"), + '<' => self.write("<"), + '>' => self.write(">"), + '"' => self.write("""), + else => unreachable, } + i = pos + 1; } - if (start < txt.len) self.write(txt[start..]); } fn writeUrlEscaped(self: *HtmlRenderer, txt: []const u8) void {