Benchmarks
Apple Silicon (M-series), July 2026. All parsers run with GFM tables, strikethrough, and task lists enabled; ferromark's non-GFM extras (heading IDs, callouts) are disabled. Output buffers are reused where APIs allow and binaries are non-PGO. ferromark keeps its secure default rendering in this published product lane, so it also performs URL and raw-HTML safety work that pulldown-cmark does not.
CommonMark 5 KB
| Parser | Throughput | vs ferromark |
|---|---|---|
| ferromark | 259.6 MiB/s | baseline |
| pulldown-cmark | 254.5 MiB/s | 0.98x |
| md4c (C) | 243.1 MiB/s | 0.94x |
| comrak | 67.9 MiB/s | 0.26x |
CommonMark 50 KB
| Parser | Throughput | vs ferromark |
|---|---|---|
| ferromark | 280.5 MiB/s | baseline |
| pulldown-cmark | 275.2 MiB/s | 0.98x |
| md4c (C) | 253.3 MiB/s | 0.90x |
| comrak | 71.8 MiB/s | 0.26x |
Summary: 2% faster than pulldown-cmark, 11% faster than md4c, and roughly 4x faster than comrak on this fixture set. Competitor versions: pulldown-cmark 0.13.4, comrak 0.53, md4c @ 65c6c9d.
Reproduce locally
The published four-parser lane requires the pinned md4c checkout:
cd benchmarks/md4c-comparison
MD4C_DIR=/path/to/md4c cargo bench --bench comparisonFeature-parity lanes
The focused two-parser harness separates three explicit shared surfaces:
| Lane | Shared features | Raw HTML |
|---|---|---|
| CommonMark | CommonMark only | trusted/preserved |
| GFM overlap | CommonMark, tables, strikethrough, task lists | trusted/preserved |
| Extended overlap | GFM overlap, footnotes, math, superscript, callouts | trusted/preserved |
Run semantic guardrails before measuring:
cargo test --manifest-path benchmarks/pulldown-comparison/Cargo.toml
cargo bench --manifest-path benchmarks/pulldown-comparison/Cargo.tomlThese lanes are designed for like-for-like parser comparison. ferromark's secure-default result stays separate because pulldown-cmark has no equivalent URL/raw-HTML trust boundary.
Option costs
cargo bench --bench options renders one shared corpus under the dialect
presets (minimal, commonmark, gfm, default) and under individual
extension flags. Because the document stays constant, differences between
lanes show what each configuration costs on identical input — a mix of
features the corpus actually uses (tables, task lists, strikethrough) and
enabled-but-unused paths. It is not a comparison of different documents.