aboutsummaryrefslogtreecommitdiff
path: root/scripts/release_perf_smoke.sh
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-08-19 04:43:28 +0300
committerGitHub <noreply@github.com>2026-08-19 04:43:28 +0300
commita5c69beabfc82d9c3f9563eb821139b2e0f3e14f (patch)
tree9b7049e4629913dcab40d985df399acee262b67b /scripts/release_perf_smoke.sh
parent3667151744e379ac5c8f76d57203b675de8a6ebc (diff)
fix(perf): eliminate redundant terminal wake work (#2962)
* fix(perf): eliminate redundant terminal wake work * fix(perf): harden release benchmark gate * test(perf): strengthen performance guardrails
Diffstat (limited to 'scripts/release_perf_smoke.sh')
-rwxr-xr-xscripts/release_perf_smoke.sh92
1 files changed, 92 insertions, 0 deletions
diff --git a/scripts/release_perf_smoke.sh b/scripts/release_perf_smoke.sh
new file mode 100755
index 00000000..7ce1f736
--- /dev/null
+++ b/scripts/release_perf_smoke.sh
@@ -0,0 +1,92 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+if [[ $# -ne 1 ]]; then
+ echo "usage: $0 <candidate-binary>" >&2
+ exit 2
+fi
+
+candidate=$(cd "$(dirname "$1")" && pwd)/$(basename "$1")
+[[ -x "$candidate" ]] || { echo "candidate binary is not executable: $candidate" >&2; exit 1; }
+script_dir=$(cd "$(dirname "$0")" && pwd)
+repo_root=$(cd "$script_dir/.." && pwd)
+baseline=${HERDR_PERF_BASELINE_BIN:-}
+for command in jq lsof perl tmux; do
+ command -v "$command" >/dev/null || { echo "required command not found: $command" >&2; exit 1; }
+done
+if [[ -z "$baseline" ]]; then
+ command -v curl >/dev/null || { echo "required command not found: curl" >&2; exit 1; }
+fi
+
+case "$(uname -s)" in
+ Linux) platform=linux; command -v pidstat >/dev/null || { echo "required command not found: pidstat" >&2; exit 1; } ;;
+ Darwin) platform=macos ;;
+ *) echo "release performance smoke supports Linux and macOS" >&2; exit 1 ;;
+esac
+case "$(uname -m)" in
+ x86_64|amd64) arch=x86_64 ;;
+ arm64|aarch64) arch=aarch64 ;;
+ *) echo "unsupported architecture: $(uname -m)" >&2; exit 1 ;;
+esac
+
+root=$(mktemp -d /var/tmp/herdr-release-perf-smoke.XXXXXX)
+cleanup() { rm -rf "$root"; }
+trap cleanup EXIT
+trap 'exit 130' INT
+trap 'exit 143' TERM
+mkdir -p "$root/results"
+
+if [[ -z "$baseline" ]]; then
+ baseline_version=$(jq -er '.version' "$repo_root/website/latest.json")
+ baseline="$root/herdr-baseline"
+ curl -fL --retry 3 \
+ "https://github.com/herdrdev/herdr/releases/download/v${baseline_version}/herdr-${platform}-${arch}" \
+ -o "$baseline"
+ chmod +x "$baseline"
+else
+ baseline=$(cd "$(dirname "$baseline")" && pwd)/$(basename "$baseline")
+fi
+[[ -x "$baseline" ]] || { echo "baseline binary is not executable: $baseline" >&2; exit 1; }
+
+case_script="$script_dir/release_perf_case.sh"
+seconds=${HERDR_PERF_SAMPLE_SECONDS:-10}
+warmup=${HERDR_PERF_WARMUP_SECONDS:-3}
+
+for round in 1 2; do
+ if [[ $round -eq 1 ]]; then variants="baseline candidate"; else variants="candidate baseline"; fi
+ for scenario in hidden50 visible30; do
+ for variant in $variants; do
+ if [[ $variant == baseline ]]; then binary=$baseline; else binary=$candidate; fi
+ "$case_script" "$binary" "$variant" "$scenario" "$round" "$seconds" "$warmup" "$root/results" "$platform"
+ done
+ done
+done
+
+mean_total() {
+ awk '{ sum += $1; count++ } END { if (!count) exit 1; printf "%.3f", sum/count }' \
+ "$root/results/$1/$2/r1/total-cpu.txt" \
+ "$root/results/$1/$2/r2/total-cpu.txt"
+}
+
+failed=0
+printf '\nrelease performance smoke (%s/%s, two rounds, %ss samples)\n' "$platform" "$arch" "$seconds"
+printf '%-12s %12s %12s %12s\n' scenario baseline candidate change
+for scenario in hidden50 visible30; do
+ baseline_total=$(mean_total baseline "$scenario")
+ candidate_total=$(mean_total candidate "$scenario")
+ if awk -v before="$baseline_total" -v after="$candidate_total" 'BEGIN { exit !(before <= 0 || after <= 0) }'; then
+ echo "error: $scenario measured no CPU usage; the benchmark did not exercise the binaries" >&2
+ failed=1
+ fi
+ change=$(awk -v before="$baseline_total" -v after="$candidate_total" 'BEGIN { if (before == 0) print "n/a"; else printf "%+.1f%%", (after-before)/before*100 }')
+ printf '%-12s %12s %12s %12s\n' "$scenario" "$baseline_total" "$candidate_total" "$change"
+ if awk -v before="$baseline_total" -v after="$candidate_total" 'BEGIN { exit !(after > before * 1.25 && after - before > 0.5) }'; then
+ echo "error: $scenario candidate CPU exceeds baseline by more than 25% and 0.5 CPU points" >&2
+ failed=1
+ fi
+done
+
+if [[ $failed -ne 0 ]]; then
+ exit 1
+fi
+echo "release performance smoke passed"