#!/usr/bin/env bash # Measures the spec's targets (SPEC.md section 13) on this machine, with a # release build: status on 20,000 files, a second workspace of a 15,000-file # project, land time on the server, and landings per second on one main. # Usage: tests/perf.sh [path/to/target/release] set -uo pipefail ROOT=$(cd "$(dirname "$0")/.." && pwd) BIN=${1:-$ROOT/target/release} VCS=$BIN/on WORK=$(mktemp -d) export ONSET_SAVER=0 ONSET_HOME=$WORK/home ONSET_NAME=Perf ONSET_EMAIL=perf@example.com PORT=$((20000 + RANDOM % 20000)) HOST="127.0.0.1:$PORT" SERVER_PID= cleanup() { [ -n "$SERVER_PID" ] && kill "$SERVER_PID" 2>/dev/null rm -rf "$WORK" } trap cleanup EXIT cd "$WORK" ms() { python3 -c "import time; print(int(time.time()*1000))"; } best() { # runs a command 5 times, prints the fastest in ms local b=999999 for _ in 1 2 3 4 5; do local t0; t0=$(ms); "$@" >/dev/null 2>&1; local t=$(($(ms) - t0)) [ "$t" -lt "$b" ] && b=$t done echo "$b" } files() { # folder, count python3 - "$1" "$2" <<'EOF' import os, sys root, n = sys.argv[1], int(sys.argv[2]) for i in range(n): d = os.path.join(root, "src", f"m{i // 20:04d}") os.makedirs(d, exist_ok=True) with open(os.path.join(d, f"f{i:05d}.ts"), "w") as f: f.write(f"export const v{i} = {i};\n" * 30) EOF } # Status on 20,000 files. "$VCS" init big >/dev/null files big 20000 "$VCS" -C big land -m "20k files" >/dev/null echo "status, 20,000 files, nothing changed: $(best "$VCS" -C big status) ms" printf 'edit\n' >> big/src/m0500/f10000.ts echo "status, 20,000 files, one changed: $(best "$VCS" -C big status) ms" # A second workspace of a 15,000-file project, through a host. "$BIN/onset-server" user add perf --name Perf --email perf@example.com --data "$WORK/server" > token ONSET_SERVER_LOG=1 "$BIN/onset-server" serve --data "$WORK/server" --listen "$HOST" --threads 16 2>"$WORK/server.log" & SERVER_PID=$! for _ in $(seq 50); do curl -s "http://$HOST/.well-known/onset.json" >/dev/null && break; sleep 0.1; done "$VCS" login "$HOST" --token "$(cat token)" >/dev/null "$VCS" init mid >/dev/null files mid 15000 "$VCS" -C mid land -m "15k files" >/dev/null t0=$(ms); "$VCS" -C mid publish "$HOST/perf/mid" >/dev/null; echo "publish 15,000 files: $(($(ms) - t0)) ms" t0=$(ms); "$VCS" get "$HOST/perf/mid" ws1 >/dev/null; echo "first workspace, 15,000 files (objects already here): $(($(ms) - t0)) ms" t0=$(ms); "$VCS" get "$HOST/perf/mid" ws2 >/dev/null; echo "second workspace, 15,000 files: $(($(ms) - t0)) ms" t0=$(ms); ONSET_HOME=$WORK/fresh "$VCS" login "$HOST" --token "$(cat token)" >/dev/null; ONSET_HOME=$WORK/fresh "$VCS" get "$HOST/perf/mid" ws3 >/dev/null; echo "workspace on a new machine (downloads everything): $(($(ms) - t0)) ms" # Landing: one at a time, then 64 at once. for i in $(seq 1 64); do "$VCS" get "$HOST/perf/mid" "a$i" >/dev/null; printf 'agent %s\n' "$i" > "a$i/agent-$i.txt"; done t0=$(ms); "$VCS" -C a1 land -m "One land" >/dev/null; echo "one land, whole command: $(($(ms) - t0)) ms" t0=$(ms) pids=() for i in $(seq 2 64); do "$VCS" -C "a$i" land -m "Agent $i" >/dev/null 2>&1 & pids+=($!); done wait "${pids[@]}" total=$(($(ms) - t0)) n=$(curl -s -H "authorization: Bearer $(cat token)" "http://$HOST/v1/projects/perf/mid" | python3 -c 'import json,sys; print(json.load(sys.stdin)["main"]["n"])') echo "63 agents landing at once: $total ms for all, main at $n (expected 65)" # The server's own time per land, from its request log ("POST .../land → 200 in 1.23ms"). grep 'POST /v1/projects/perf/mid/land' "$WORK/server.log" | sed -E 's/.* in ([0-9.]+)(µs|ms|s)$/\1 \2/' | python3 -c ' import sys ms = sorted(float(v) * {"µs": 0.001, "ms": 1, "s": 1000}[u] for v, u in (l.split() for l in sys.stdin if l.strip())) print(f"server time per land: median {ms[len(ms)//2]:.1f} ms, slowest {ms[-1]:.1f} ms, {len(ms)} lands; one main lands about {1000/ms[len(ms)//2]:.0f} per second") '