Benchmarks

Yamark performance against other YAML and Markdown formatters.

Yamark formats a 4 MB Markdown document in 109 ms and a 4 MB YAML file in 69 ms. The next-fastest tool on each is dprint-markdown (349 ms) and yamlfmt (187 ms). On a directory of 500 YAML files (50 MB), yamark finishes in 133 ms; the next-fastest formatter, deno-fmt, takes 2.6 s.

There is one comparison per input kind, and each lists every tool whose own CLI formats that input natively, used simply: no formatting options, no shims, no adapters. The tool roster therefore differs by input kind.

One generated 4 MB Markdown document (big.md): prose paragraphs with links - some longer than the line width - and nested lists with mixed markers. Each tool’s CLI formats the file in place; time includes process startup. Time is the median of 10 measured runs after 2 warmup runs, on a fresh copy of the file each run. Memory is median peak RSS.

Formatter Time Memory vs yamark
yamark 109 ms 12.8 MB 1x
dprint-markdown 349 ms 172.8 MB 3.2x slower
deno-fmt 376 ms 482.0 MB 3.5x slower
panache 399 ms 33.0 MB 3.7x slower
prettier 1.8 s 596.4 MB 16.2x slower
mdformat 3.1 s 153.4 MB 28.9x slower

One generated 4 MB YAML file (big.yaml): block maps and sequences, block scalars, and comments. Same procedure as the Markdown comparison.

Formatter Time Memory vs yamark
yamark 69 ms 51.7 MB 1x
yamlfmt 187 ms 248.3 MB 2.7x slower
deno-fmt 761 ms 142.9 MB 11.1x slower
dprint-yaml 1.2 s 118.7 MB 16.7x slower
yamlfix 7.3 s 268.2 MB 106.6x slower
prettier 20.0 s 846.1 MB 290.5x slower

The same 4 MB document shape (big-with-frontmatter.md) with a 200 KB deliberately unformatted YAML front matter block - about a third of the document’s lines are YAML. The Front matter column reports what each tool did with that block: formatted (rewrote it), untouched (passed it through), or not preserved (broke the delimiters).

Formatter Time Memory Front matter vs yamark
yamark 113 ms 15.4 MB formatted 1x
dprint-markdown 346 ms 173.1 MB untouched 3.1x slower
deno-fmt 430 ms 587.6 MB formatted 3.8x slower
prettier 1.9 s 580.8 MB formatted 16.5x slower
mdformat 3.8 s 180.0 MB not preserved 33.4x slower
panache 6.6 s 41.0 MB formatted 58.7x slower

The harness derives that column from the output bytes: trailing-whitespace trimming does not count as formatting. dprint’s Markdown plugin passes front matter through unformatted, and mdformat (installed without its front-matter plugin) reads the opening --- as a thematic break and corrupts the block.

500 generated YAML service-configuration files of about 100 KB each (50 MB in total). Each tool is passed the directory root once and discovers the files itself; every run is verified to have reformatted all 500 files. Time is the median of 3 measured runs after 1 warmup run, on a fresh copy of the corpus each run.

Formatter Time User CPU Throughput vs yamark
yamark 0.133 s 1.087 s 374.9 MB/s 1x
deno-fmt 2.639 s 33.668 s 18.9 MB/s 19.8x slower
dprint-yaml 3.112 s 39.949 s 16.1 MB/s 23.3x slower
yamlfmt 3.967 s 4.447 s 12.6 MB/s 29.8x slower
prettier 46.748 s 71.863 s 1.07 MB/s 350.8x slower
yamlfix 179.255 s 178.717 s 0.28 MB/s 1345.0x slower

Yamark formats the directory in parallel (as do deno-fmt and dprint), so wall time can beat user CPU time; the User CPU column is the single-core comparison, and yamark is fastest on that column too. Throughput is input MB/s.

How to read these results

Every number comes from the same harness (tools/bench/big.py and tools/bench/run.py in the repository), running each tool the way a user would: its own CLI, default configuration, no formatting options, against deterministic generated corpora. The comparison set is the other formatters in the space - deno-fmt, dprint-markdown, dprint-yaml, mdformat, panache, prettier, yamlfix, yamlfmt.

Two harness details keep that comparison clean without changing how any tool is invoked:

  • panache and dprint cache format results. The harness redirects each tool’s cache into the benchmark work directory and clears it between repetitions, so every timed run formats from scratch rather than replaying a cached result.
  • dprint has no built-in plugins, so it runs with a config file that names its first-party plugin for the input kind (Markdown or YAML) and sets nothing else.

Lint fixers with an autofix mode (pymarkdown, markdownlint-cli2) are not formatters, so they are not part of the comparison. The harness can still run them via --tools.

Measured on a MacBook Pro (Apple M4 Max, macOS arm64). Tool versions: yamark 0.1.0, deno 2.9.4 (stable, release, aarch64-apple-darwin), dprint 0.55.2, yamlfmt 0.21.0 (Homebrew), prettier 3.8.3, yamlfix 1.19.1, panache 2.46.0, mdformat 1.0.0.

The tables render the latest checked-in artifacts - ab72bb5 for the single-file comparisons and d9bbab3 for the directory comparison - which record the full per-run timings, output hashes, git commit, and host details. A table renders only if every tool in its roster completed the benchmark; degraded runs are never shown as smaller tables.

Reproducing

tools/bench/big.py
tools/bench/run.py --invocation directory --files 500 --items 540 \
  --reps 3 --warmups 1 \
  --tools yamark,yamlfmt,prettier,yamlfix,dprint-yaml,deno-fmt

The corpora are generated deterministically, so the same commands reproduce the same inputs anywhere; each script writes a JSON artifact under docs/benchmarks/.