Skip to content
mycli.usage.kdl
name "mycli"
flag "-v --verbose" help="Enable verbose output"
arg "<file>" help="File to process"
cmd "deploy" { flag "--env <env>" }

Benchmarks

Parser overhead

What parsing mise use -g node@20 costs each framework, against a shadow of mise's CLI: 211 commands, 711 flags. Every program on both cards is generated from that one checked-in spec.

usage-rs vs clap, bpaf

wall time, in-process parse throughput How this is measured Each parser runs repeatedly inside one process; process startup is excluded, so these bars are not full CLI invocation times. The chart reports the fastest per-parse time from many short rounds. Minima and their ratios drift a few percent between runs and machines, hence the ~. Instructions for one cold parse, which do not drift: 4,155 · 5.89M · 21.9M, agreeing across two machines to 0.15%.

usage-rs0.19 µs
clap480 µs· ~2,500× more
bpaf1,600 µs· ~8,200× more

usage-rs starts from compiler-emitted static tables and scans only the current command's flags plus inherited globals. clap and bpaf build a parser before they can use one Where their time goes Most of clap's is constructing and validating its command tree. bpaf's is larger because it assembles a combinator tree per run as well, which reusing the parser across parses only halves. . Heap allocations for a bare parse: zero, against clap's 6,560.

usage-go vs cobra, urfave/cli, kong

wall time, in-process parse throughput How this is measured The same way as the Rust card, by a harness written to match it: each parser runs repeatedly inside one process and the fastest per-parse time from many short rounds is reported, with the collector run between rounds rather than inside them. Process startup is excluded — a Go process is about a millisecond old before main, which no parser can touch. Whole-process cost, and instructions for one parse: go/README.md.

usage-go5.9 µs
cobra110 µs· ~18× more
urfave/cli v3200 µs· ~34× more
kong3.0 ms· ~500× more

usage-go binds against package-level tables the linker laid out before main. cobra and urfave build a command tree per process and kong reflects over a struct, none of which a spec-driven parser has to do. Instructions for the same parse: 123k vs cobra's 2.8M, urfave/cli's 5.8M, kong's 66.7M — and 1,955 for the binder under usage-go's typed front door.

Methodology and raw numbers: go/README.md · tasks/perf-shadow.sh · time-sweep.rs

MIT LicenseCopyright © 2026jdx.dev