Skip to content

itIsJim/script-benchmarker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

script-benchmarker

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)

Architecture

.
├── 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 wait4 rusage plus a 50ms libproc (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-motion respected.

Quick start

Fastest tour — one command, ends in your browser:

./docs/demo.sh

It 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 ui

compare 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.

What gets measured

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.

Sample task

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.

Requirements

  • macOS or Linux, a C++17 compiler, make
  • Node.js ≥ 18 (for the UI only)

Roadmap

  • 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

About

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.

Contributing

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).

Citing

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.

License

MIT. Dependencies (D3, Barba.js, Vite, TypeScript) are fetched from npm under their own licenses; nothing is vendored.

About

Benchmark any script in any language — wall/CPU time, memory, empirical Big-O, and output structure quality.

Topics

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors