Files
mapsize/rust/bench/micro.py
T

46 lines
2.1 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Runs the Go `go test -bench` suite and the Rust bench example
interleaved for several rounds and prints the best time per op of each.
rust/bench/micro.py GO_TUI_TEST GO_TREEMAP_TEST RUST_BENCH [ROUNDS]
Build the inputs with `go test -c ./internal/tui`, `go test -c
./internal/treemap` and `cargo build --release --example bench`. The Go tui
test binary must run from internal/tui, so run this from the repo root.
"""
import re, subprocess, sys
go_tui, go_tm, rust = sys.argv[1:4]
rounds = int(sys.argv[4]) if len(sys.argv) > 4 else 5
names = { # rust name -> go name
"treemap/Squarify(300)": "Squarify", "treemap/Neighbour(300)": "Neighbour",
"tui/BigColdFrame": "BigColdFrame", "tui/BigResize": "BigResize",
"tui/BigFlatDirCold": "BigFlatDirCold", "tui/BigNavigate": "BigNavigate",
"tui/BigFilter/size > 1MB": "BigFilter/size_>_1MB",
"tui/BigFilter/*.dat AND size > 500k": "BigFilter/*.dat_AND_size_>_500k",
"tui/BigFilter/path contains sub3": "BigFilter/path_contains_sub3",
}
unit = {"ns": 1e-9, "µs": 1e-6, "ms": 1e-3, "s": 1}
go_best, rust_best = {}, {}
def keep(d, k, v):
d[k] = min(d.get(k, v), v)
for _ in range(rounds):
for exe, cwd in ((go_tui, "internal/tui"), (go_tm, "internal/treemap")):
out = subprocess.run([exe, "-test.run=NONE", "-test.bench=.", "-test.benchtime=1s"], cwd=cwd, capture_output=True, text=True).stdout
for m in re.finditer(r"^Benchmark(\S+?)-\d+\s+\d+\s+([\d.]+) ns/op", out, re.M):
keep(go_best, m[1], float(m[2]) * 1e-9)
out = subprocess.run([rust], capture_output=True, text=True).stdout
for m in re.finditer(r"^(\S.*?)\s+\d+ ops\s+([\d.]+)(ns|µs|ms|s)/op", out, re.M):
keep(rust_best, m[1].strip(), float(m[2]) * unit[m[3]])
def fmt(s):
return f"{s * 1e6:.1f} µs" if s < 1e-3 else f"{s * 1e3:.2f} ms"
print(f"Best of {rounds} interleaved rounds\n")
print("| benchmark | Go | Rust | speed-up |\n|---|---:|---:|---:|")
for r, g in names.items():
if r in rust_best and g in go_best:
print(f"| {r} | {fmt(go_best[g])} | {fmt(rust_best[r])} | {go_best[g] / rust_best[r]:.2f}× |")