Skip to content

Commit eb40c9e

Browse files
authored
docs(bench): publish TypeScript renderer results (#539)
Refresh the published benchmark tables and charts with @tanstack/markdown and markdown-it-ts results, and document the comparison methodology.
1 parent 72c8e83 commit eb40c9e

6 files changed

Lines changed: 348 additions & 276 deletions

File tree

README.md

Lines changed: 57 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -210,79 +210,87 @@ Ox Content is positioned both as a document generator and as a high-performance
210210

211211
<!-- benchmark:tables:start -->
212212

213-
_Benchmark sweep generated on 2026-07-18 (median of 3 runs). Numbers track the host machine; the relative ordering between engines is the stable signal. Regenerated by `scripts/render-benchmark-tables.mjs`._
213+
_Benchmark sweep generated on 2026-07-30 (median of 7 runs). Numbers track the host machine; the relative ordering between engines is the stable signal. Regenerated by `scripts/render-benchmark-tables.mjs`._
214214

215-
_Environment: runner `blacksmith-32vcpu-ubuntu-2404`, Node `v24.18.0`, Bun `1.3.14`, CPU `AMD EPYC`, 32 logical cores._
215+
_Environment: runner `blacksmith-32vcpu-ubuntu-2404`, Node `v24.18.1`, Bun `1.3.14`, CPU `Intel(R) Xeon(R) Processor`, 32 logical cores._
216216

217217
### Parse Only (48.7 KB)
218218

219219
| Library | ops/sec | avg time | throughput |
220220
| ------------------------------------- | ------: | -------: | ----------: |
221-
| `ox-content (native)` | 8,417 | 0.12 ms | 400.53 MB/s |
222-
| `pulldown-cmark` | 4,952 | 0.20 ms | 235.63 MB/s |
223-
| `xai-grok-markdown-core (Grok Build)` | 4,733 | 0.21 ms | 225.22 MB/s |
224-
| `@ox-content/napi` | 4,199 | 0.24 ms | 199.80 MB/s |
225-
| `satteri` | 2,174 | 0.46 ms | 103.43 MB/s |
226-
| `md4x (napi)` | 1,041 | 0.96 ms | 49.55 MB/s |
227-
| `md4w (md4c)` | 923 | 1.08 ms | 43.93 MB/s |
228-
| `markdown-it` | 704 | 1.42 ms | 33.49 MB/s |
229-
| `marked` | 448 | 2.23 ms | 21.32 MB/s |
230-
| `@mizchi/markdown` | 44 | 22.73 ms | 2.09 MB/s |
231-
| `remark` | 30 | 33.40 ms | 1.42 MB/s |
221+
| `ox-content (native)` | 7,494 | 0.13 ms | 356.63 MB/s |
222+
| `pulldown-cmark` | 4,867 | 0.21 ms | 231.62 MB/s |
223+
| `xai-grok-markdown-core (Grok Build)` | 4,167 | 0.24 ms | 198.28 MB/s |
224+
| `@ox-content/napi` | 3,950 | 0.25 ms | 187.97 MB/s |
225+
| `satteri` | 2,372 | 0.42 ms | 112.86 MB/s |
226+
| `md4x (napi)` | 921 | 1.09 ms | 43.81 MB/s |
227+
| `md4w (md4c)` | 893 | 1.12 ms | 42.50 MB/s |
228+
| `markdown-it-ts` | 811 | 1.23 ms | 38.60 MB/s |
229+
| `markdown-it` | 700 | 1.43 ms | 33.32 MB/s |
230+
| `@tanstack/markdown` | 687 | 1.46 ms | 32.68 MB/s |
231+
| `marked` | 444 | 2.25 ms | 21.12 MB/s |
232+
| `@mizchi/markdown` | 48 | 20.75 ms | 2.29 MB/s |
233+
| `remark` | 32 | 31.64 ms | 1.50 MB/s |
232234

233235
### Parse + Render (48.7 KB)
234236

235237
| Library | ops/sec | avg time | throughput |
236238
| ---------------------------- | ------: | -------: | ----------: |
237-
| `ox-content (native)` | 5,679 | 0.18 ms | 270.25 MB/s |
238-
| `@ox-content/napi` | 4,799 | 0.21 ms | 228.39 MB/s |
239-
| `pulldown-cmark + push_html` | 4,728 | 0.21 ms | 224.97 MB/s |
240-
| `Bun.markdown.html` | 3,947 | 0.25 ms | 187.81 MB/s |
241-
| `md4x (napi)` | 3,845 | 0.26 ms | 182.96 MB/s |
242-
| `md4w (md4c)` | 2,148 | 0.47 ms | 102.23 MB/s |
243-
| `satteri` | 1,449 | 0.69 ms | 68.95 MB/s |
244-
| `markdown-it` | 574 | 1.74 ms | 27.31 MB/s |
245-
| `marked` | 390 | 2.56 ms | 18.58 MB/s |
246-
| `@mizchi/markdown` | 347 | 2.88 ms | 16.53 MB/s |
247-
| `micromark` | 31 | 32.46 ms | 1.47 MB/s |
248-
| `remark` | 27 | 36.68 ms | 1.30 MB/s |
239+
| `ox-content (native)` | 5,195 | 0.19 ms | 247.19 MB/s |
240+
| `pulldown-cmark + push_html` | 4,566 | 0.22 ms | 217.28 MB/s |
241+
| `@ox-content/napi` | 4,532 | 0.22 ms | 215.66 MB/s |
242+
| `md4x (napi)` | 3,437 | 0.29 ms | 163.56 MB/s |
243+
| `Bun.markdown.html` | 3,107 | 0.32 ms | 147.87 MB/s |
244+
| `md4w (md4c)` | 2,129 | 0.47 ms | 101.30 MB/s |
245+
| `satteri` | 1,323 | 0.76 ms | 62.93 MB/s |
246+
| `markdown-it-ts` | 676 | 1.48 ms | 32.16 MB/s |
247+
| `markdown-it` | 563 | 1.77 ms | 26.81 MB/s |
248+
| `@tanstack/markdown` | 426 | 2.35 ms | 20.28 MB/s |
249+
| `marked` | 405 | 2.47 ms | 19.26 MB/s |
250+
| `@mizchi/markdown` | 287 | 3.48 ms | 13.67 MB/s |
251+
| `micromark` | 32 | 30.89 ms | 1.54 MB/s |
252+
| `remark` | 27 | 37.31 ms | 1.28 MB/s |
249253

250254
### Parse Only (~1 MB)
251255

252256
| Library | ops/sec | avg time | throughput |
253257
| ------------------------------------- | ------: | ---------: | ----------: |
254-
| `ox-content (native)` | 379 | 2.64 ms | 387.44 MB/s |
255-
| `pulldown-cmark` | 231 | 4.33 ms | 236.54 MB/s |
256-
| `xai-grok-markdown-core (Grok Build)` | 221 | 4.53 ms | 225.74 MB/s |
257-
| `@ox-content/napi` | 192 | 5.21 ms | 196.34 MB/s |
258-
| `satteri` | 89 | 11.25 ms | 90.97 MB/s |
259-
| `md4x (napi)` | 45 | 22.04 ms | 46.42 MB/s |
260-
| `md4w (md4c)` | 43 | 23.31 ms | 43.90 MB/s |
261-
| `markdown-it` | 19 | 53.79 ms | 19.02 MB/s |
262-
| `marked` | 16 | 62.87 ms | 16.27 MB/s |
263-
| `@mizchi/markdown` | 1 | 786.15 ms | 1.30 MB/s |
264-
| `remark` | 1 | 1234.09 ms | 0.83 MB/s |
258+
| `ox-content (native)` | 313 | 3.20 ms | 320.21 MB/s |
259+
| `pulldown-cmark` | 219 | 4.56 ms | 224.20 MB/s |
260+
| `xai-grok-markdown-core (Grok Build)` | 188 | 5.33 ms | 192.08 MB/s |
261+
| `@ox-content/napi` | 175 | 5.71 ms | 179.05 MB/s |
262+
| `satteri` | 81 | 12.34 ms | 82.94 MB/s |
263+
| `md4w (md4c)` | 42 | 24.09 ms | 42.46 MB/s |
264+
| `md4x (napi)` | 41 | 24.24 ms | 42.21 MB/s |
265+
| `@tanstack/markdown` | 24 | 42.05 ms | 24.33 MB/s |
266+
| `markdown-it-ts` | 21 | 47.31 ms | 21.62 MB/s |
267+
| `markdown-it` | 20 | 49.38 ms | 20.72 MB/s |
268+
| `marked` | 17 | 59.01 ms | 17.34 MB/s |
269+
| `@mizchi/markdown` | 1 | 681.41 ms | 1.50 MB/s |
270+
| `remark` | 1 | 1571.13 ms | 0.65 MB/s |
265271

266272
### Parse + Render (~1 MB)
267273

268274
| Library | ops/sec | avg time | throughput |
269275
| ---------------------------- | ------: | ---------: | ----------: |
270-
| `ox-content (native)` | 251 | 3.99 ms | 256.68 MB/s |
271-
| `pulldown-cmark + push_html` | 221 | 4.52 ms | 226.25 MB/s |
272-
| `@ox-content/napi` | 203 | 4.93 ms | 207.66 MB/s |
273-
| `Bun.markdown.html` | 186 | 5.37 ms | 190.39 MB/s |
274-
| `md4x (napi)` | 176 | 5.67 ms | 180.29 MB/s |
275-
| `md4w (md4c)` | 105 | 9.55 ms | 107.17 MB/s |
276-
| `satteri` | 56 | 17.92 ms | 57.10 MB/s |
277-
| `markdown-it` | 15 | 65.95 ms | 15.51 MB/s |
278-
| `marked` | 14 | 73.34 ms | 13.95 MB/s |
279-
| `@mizchi/markdown` | 11 | 93.52 ms | 10.94 MB/s |
280-
| `micromark` | 1 | 860.47 ms | 1.19 MB/s |
281-
| `remark` | 1 | 1488.07 ms | 0.69 MB/s |
276+
| `ox-content (native)` | 218 | 4.58 ms | 223.26 MB/s |
277+
| `pulldown-cmark + push_html` | 201 | 4.97 ms | 205.71 MB/s |
278+
| `@ox-content/napi` | 193 | 5.19 ms | 197.05 MB/s |
279+
| `md4x (napi)` | 156 | 6.40 ms | 159.99 MB/s |
280+
| `Bun.markdown.html` | 140 | 7.16 ms | 142.98 MB/s |
281+
| `md4w (md4c)` | 108 | 9.27 ms | 110.41 MB/s |
282+
| `satteri` | 73 | 13.77 ms | 74.29 MB/s |
283+
| `markdown-it-ts` | 18 | 54.08 ms | 18.92 MB/s |
284+
| `@tanstack/markdown` | 17 | 57.30 ms | 17.86 MB/s |
285+
| `markdown-it` | 17 | 58.81 ms | 17.40 MB/s |
286+
| `marked` | 16 | 62.50 ms | 16.37 MB/s |
287+
| `@mizchi/markdown` | 12 | 81.45 ms | 12.56 MB/s |
288+
| `micromark` | 1 | 765.78 ms | 1.34 MB/s |
289+
| `remark` | 1 | 1739.84 ms | 0.59 MB/s |
282290

283291
<!-- benchmark:tables:end -->
284292

285-
The benchmark tables above are regenerated from a clean Blacksmith 32 vCPU CI environment by the [Benchmark docs workflow](.github/workflows/benchmark-docs.yml); run `OX_CONTENT_BENCHMARK_RUNS=7 vp run bench:docs` to refresh them locally. Ox Content leads every comparison: 1.95× ahead of the next-fastest parser (`satteri`) on parse-only and 1.65× ahead of `md4x (napi)` on parse+render at 48.7 KB, and it holds that lead at ~1 MB (2.7× / 1.6×) while sustaining ~148–168 MB/s. The incremental CST parser (`@mizchi/markdown`) and the `unified`/`remark` and `micromark` pipelines fall to ~1 op/sec at 1 MB. See `node benchmarks/bundle-size/parse-benchmark.mjs` for the full sweep across small, medium, large, and ~1 MB inputs.
293+
The benchmark tables above are regenerated from a clean Blacksmith 32 vCPU CI environment by the [Benchmark docs workflow](.github/workflows/benchmark-docs.yml); run `OX_CONTENT_BENCHMARK_RUNS=7 vp run bench:docs` to refresh them locally. Against the TypeScript renderers, the JavaScript-facing `@ox-content/napi` row is 4.9–5.7× faster to parse and 6.7–10.6× faster to parse+render at 48.7 KB; at ~1 MB the leads grow to 7.3–8.3× and 10.7–11.4×. `@tanstack/markdown` uses `parseMarkdown` and `renderHtml`, while `markdown-it-ts` uses `parse` and `render` on a reused instance. See `node benchmarks/bundle-size/parse-benchmark.mjs` for the full sweep across small, medium, large, and ~1 MB inputs.
286294

287295
Run the benchmark with:
288296

0 commit comments

Comments
 (0)