Benchmarks
Wall-clock formatting speed of badness against
tex-fmt and
latexindent, measured with
hyperfine. Every tool formats stdin → stdout, so the comparison is free of
file-mutation and exit-code noise.
This is not a quality gate and not a parity target. Timings are machine- and
run-dependent, and these numbers measure speed only, never output equivalence.
The tools also do different work: latexindent only indents by default and does
no line reflow, while badness and tex-fmt wrap—so a raw speed comparison is
a snapshot of each tool at its defaults, not equal work. Treat the ratios, not
the absolute milliseconds, as the takeaway.
The figures below are regenerated manually with task bench and committed as a
machine-readable artifact (benches/benchmark_results.json); they are never
re-measured when this site is built or in CI.
How it is measured
Each tool is invoked exactly as a user would pipe a document through it:
| Tool | Invocation |
|---|---|
badness | badness format --no-config --stdin-filepath bench.tex |
tex-fmt | tex-fmt --stdin |
latexindent | latexindent -g /dev/null - |
The corpus is real LaTeX: a committed small.tex baseline plus larger documents
(cv.tex, masters_dissertation.tex, phd_dissertation.tex) fetched by
benches/documents/download.sh from a pinned tex-fmt release. Documents
badness cannot yet format (parser diagnostics) are skipped, as are comparison
tools missing from PATH.
Whole-project (folder) benchmark
One entry, project, measures recursive folder formatting rather than a
single file: each tool walks a real multi-file LaTeX thesis (the pinned
kks32/phd-thesis-template, its .tex fragments) and formats every file in
read-only --check mode—the folder analog of the stdin -> stdout runs above
(full formatting work, nothing written). Only badness and tex-fmt appear
here: latexindent has no recursive directory mode, so it is excluded from this
comparison by design.
| Tool | Invocation |
|---|---|
badness | badness format --check <dir> |
tex-fmt | tex-fmt --check --recursive <dir> |
The benchmark runs against a throwaway copy of the fetched project so both tools
walk an identical, un-gitignored, .tex-only tree (badness format is
.tex-only, while tex-fmt would otherwise also touch .bib/.cls). Any file
badness cannot format yet is dropped from both tools, keeping the comparison
symmetric. This is a different mode from the single-file rows, so read its ratio
on its own terms, not against them.
Setup
- badness:
0.7.0 - tex-fmt:
0.5.7 - latexindent:
3.24.7 - backend: hyperfine (min runs: 3)
- host: linux/x86_64, Intel(R) Core(TM) Ultra 7 155U
- generated: 2026-07-09T10:40:47Z
Results
badness. Each dot is one document formatted by one tool; the vertical position is mean wall-clock time as a ratio to badness on a log scale, so badness lies on the dashed baseline at 1, faster tools fall below it and slower tools rise above. Color distinguishes documents; hover a dot for the exact millisecond figures.Data table
small.tex (baseline) (1233 bytes, 48 lines)
| Tool | Mean (ms) | Min (ms) | Max (ms) | Relative |
|---|---|---|---|---|
| badness | 2.6297 | 1.4819 | 5.1301 | baseline |
| tex-fmt | 2.2636 | 1.1841 | 4.6620 | 1.2× faster |
| latexindent | 92.6401 | 87.4192 | 105.5402 | 35.2× slower |
cv.tex (6273 bytes, 275 lines)
| Tool | Mean (ms) | Min (ms) | Max (ms) | Relative |
|---|---|---|---|---|
| badness | 3.5055 | 2.1203 | 6.1287 | baseline |
| tex-fmt | 2.4588 | 1.3104 | 5.5154 | 1.4× faster |
| latexindent | 110.4370 | 88.3253 | 148.6525 | 31.5× slower |
masters_dissertation.tex (95383 bytes, 2458 lines)
| Tool | Mean (ms) | Min (ms) | Max (ms) | Relative |
|---|---|---|---|---|
| badness | 21.7922 | 18.1965 | 30.6706 | baseline |
| tex-fmt | 3.5095 | 2.2134 | 8.2749 | 6.2× faster |
| latexindent | 2362.2828 | 2291.5633 | 2486.9880 | 108.4× slower |
project (12 files) (47190 bytes, 1005 lines)
| Tool | Mean (ms) | Min (ms) | Max (ms) | Relative |
|---|---|---|---|---|
| badness | 4.5856 | 2.5611 | 9.0537 | baseline |
| tex-fmt | 3.6836 | 1.4920 | 6.5271 | 1.2× faster |