Benchmark any script in any language and visualize the results. Give it a command and a data sample; it records wall time, CPU time, peak memory, a memory/CPU timeline, captured logs, and an empirical big-O estimate — in the terminal and in an animated web dashboard.
It is built for comparing competing implementations of the same task: one input file, several contenders, and a clear ranking. A contender is any shell command, so any language with a runtime works; the bundled sample includes JavaScript, Python, Go, Rust, C/C++, and Java.
Docs: Usage guide (setup → run → view) · Methodology (how metrics are measured and charts designed) · Walkthrough (guided tour)
.
├── bench # CLI entry point (compare + run + list + ui)
├── runner/ # C++17 measurement engine (zero dependencies)
│ └── src/ # fork/exec, rusage, libproc//proc sampling,
│ # log capture, big-O least-squares fitting
├── ui/ # TypeScript + Vite + Barba.js + D3 dashboard
│ ├── index.html # dashboard: KPI tiles, comparison charts, table
│ └── run.html # run detail: timelines, complexity fit, logs
├── docs/ # USAGE, METHODOLOGY, walkthrough, demo script
├── samples/
│ └── word2vec/ # demo task + scripts in 6 languages
└── results/ # one folder per run: result.json + logs
- C/C++ runner for minimal measurement overhead: the child process is
spawned directly, CPU/memory come from
wait4rusage plus a 50mslibproc(macOS) //proc(Linux) sampler, and logs stream through pipes. - Barba.js + D3 UI: Barba.js drives seamless page transitions; D3 drives
the charts and their animations — comparison bars race in at a speed
proportional to each run's measured time, and the big-O curve traces
itself with a clock driven by the fitted cost model. Crosshair tooltips,
loading skeletons, light/dark mode,
prefers-reduced-motionrespected.
Fastest tour — one command, ends in your browser:
./docs/demo.shIt benchmarks the same word2vec nearest-neighbor task in every language you
have a toolchain for (Python, numpy, Node.js, Go, Rust, C++, Java), prints
the terminal summary, then opens the web dashboard so you can explore
timelines, complexity fits, and logs interactively. See docs/USAGE.md for
the full setup → run → view guide and docs/walkthrough.md for the guided
tour.
Or with your own task — one folder, one command:
# Put everything in a folder: scripts/ (any language mix), data/ (the
# sample), README (the task). Then bulk-compare all of it:
./bench compare samples/my-task
# Only one script? Same command:
./bench compare my_script.py --data input.tsv
# Open the web dashboard (http://localhost:5173).
./bench uicompare auto-discovers the data and scripts, compiles what needs
compiling (Go/Rust/C/C++/Java), skips missing toolchains, benchmarks each
contender with big-O scaling, and prints the ranking. For custom command
lines (flags, pipelines, other runtimes) there's full-control
./bench run --name X --cmd "sort {data} | uniq -c" --data input.tsv —
anything you can type into a shell is a contender. See
docs/USAGE.md §2.
| Metric | How |
|---|---|
| Wall time | monotonic clock around the process |
| CPU time (user/sys) | wait4 rusage, includes child processes |
| Peak memory | ru_maxrss, cross-checked against the sampler |
| Memory / CPU timeline | 50ms sampling (--interval to change) |
| Logs | stdout/stderr captured to files, viewable in the UI |
| Big-O estimate | --scale: geometric ladder of input sizes, least-squares fit against O(1)…O(n³), best R² wins (simplest model preferred within noise) — see METHODOLOGY |
Every run writes results/<id>/result.json — a self-contained document the
UI (or anything else) can consume.
samples/word2vec/ — a ready-made comparison task with a data
generator, competing scripts, and a README defining the script contract:
find the top-5 nearest neighbors in an embedding space. Six languages
implement the same algorithm — pure Python, numpy, Node.js typed arrays,
Go, Rust, C++, and Java — and all emit byte-identical output. Same big-O,
very different constants. This is what ./docs/demo.sh runs.
Correctness across scripts: all scripts print their answer to stdout, so
diff the stdout.log files of two runs to confirm they agree.
- macOS or Linux, a C++17 compiler,
make - Node.js ≥ 18 (for the UI only)
- Repeated runs per size (median-of-k) so sub-second scripts fit cleanly
- Side-by-side run comparison page
- Watch mode: re-run on script change
- Static export of the dashboard for sharing results
script-benchmarker treats every contender as a black-box process, so any language works, and it measures rather than estimates. It is a measurement tool, not a microbenchmarking framework: numbers are end-to-end and machine-specific by design. docs/METHODOLOGY.md documents how each metric is measured, how the complexity estimate is fitted, and what the results do and do not support.
Contributions are welcome — see CONTRIBUTING.md for the dev setup, layout, and the project's few hard conventions (the methodology doc is normative; animations must encode data; samples stay generic and deterministic).
If you use this project in academic work, see CITATION.cff (GitHub renders a "Cite this repository" button from it). The measurement methodology and its references live in docs/METHODOLOGY.md.
MIT. Dependencies (D3, Barba.js, Vite, TypeScript) are fetched from npm under their own licenses; nothing is vendored.