Files
spinifex/scripts/benchmark-gc.sh
T
2026-01-14 04:33:47 +00:00

120 lines
3.8 KiB
Bash
Executable File

#!/bin/bash
# scripts/benchmark-gc.sh
# Benchmark script to compare Go GC performance (Standard vs GreenteaGC)
set -e
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BIN_PATH="$PROJECT_ROOT/bin/hive"
DATA_DIR="$HOME/hive"
LOGS_DIR="$DATA_DIR/logs"
ITERATIONS=500
CONCURRENCY=12
# Ensure AWS profile is set
export AWS_PROFILE=hive
# Skip SSL verification for local testing
export AWS_CA_BUNDLE="$DATA_DIR/config/server.pem"
# Function to build the binary
build_binary() {
local experiment="$1"
echo "🔨 Building with GOEXPERIMENT=$experiment..."
cd "$PROJECT_ROOT"
# Clean build to ensure no stale artifacts
rm -f "$BIN_PATH"
if [ "$experiment" == "none" ]; then
go build -ldflags "-s -w" -o "$BIN_PATH" cmd/hive/main.go
else
GOEXPERIMENT="$experiment" go build -ldflags "-s -w" -o "$BIN_PATH" cmd/hive/main.go
fi
}
# Function to start services with GC tracing
start_services_traced() {
echo "🚀 Starting services with GODEBUG=gctrace=1..."
export GODEBUG=gctrace=1
"$PROJECT_ROOT/scripts/start-dev.sh" "$DATA_DIR"
sleep 10 # More time for services to stabilize
}
# Function to run load test
run_load() {
echo "🔥 Warming up (20 requests)..."
seq 20 | xargs -I{} -P $CONCURRENCY aws ec2 describe-instances > /dev/null
echo "🏃 Running load test ($ITERATIONS requests)..."
local start_time=$(date +%s%N)
seq $ITERATIONS | xargs -I{} -P $CONCURRENCY aws ec2 describe-instances > /dev/null
local end_time=$(date +%s%N)
local duration=$(( (end_time - start_time) / 1000000 ))
echo "⏱️ Load test completed in ${duration}ms"
echo "$duration" > "$LOGS_DIR/last_duration.txt"
}
# Function to analyze GC logs
analyze_logs() {
local label="$1"
echo "📊 Analyzing logs for $label..."
# Analyze the AWS Gateway log (usually the most active)
local log_file="$LOGS_DIR/awsgw.log"
if [ ! -f "$log_file" ]; then
echo "❌ Log file $log_file not found"
return
fi
# Extract GC stats: gc N @T ... total_time ...
# Format: gc 1 @0.012s 5%: 0.016+0.45+0.003 ms clock, 0.25+0.45/0.70/1.2+0.054 ms cpu, 4->4->0 MB, 5 MB goal, 8 P
local gc_count=$(grep -c "^gc " "$log_file" || echo 0)
local total_gc_ms=$(grep "^gc " "$log_file" | awk -F'ms clock' '{print $1}' | awk '{print $NF}' | awk -F'+' '{sum += $1+$2+$3} END {print sum}')
# Memory usage (max RSS of the process)
local max_rss=$(ps aux | grep "hive service awsgw start" | grep -v grep | awk '{print $6}' | sort -nr | head -n1)
local duration=$(cat "$LOGS_DIR/last_duration.txt")
echo "----------------------------------------"
echo "Results for $label:"
echo "Requests: $ITERATIONS"
echo "Concurrency: $CONCURRENCY"
echo "Total Time: ${duration}ms"
echo "Avg Latency: $(( duration / ITERATIONS ))ms"
echo "GC Cycles: $gc_count"
echo "Total GC Time: ${total_gc_ms}ms"
echo "Max RSS: ${max_rss} KB"
echo "----------------------------------------"
# Save to a summary file
echo "$label,$duration,$gc_count,$total_gc_ms,$max_rss" >> "$PROJECT_ROOT/gc_benchmark_summary.csv"
}
# Cleanup
echo "Cleaning up previous runs..."
"$PROJECT_ROOT/scripts/stop-dev.sh" || true
rm -f "$PROJECT_ROOT/gc_benchmark_summary.csv"
echo "Label,TotalTime_ms,GCCycles,TotalGCTime_ms,MaxRSS_KB" > "$PROJECT_ROOT/gc_benchmark_summary.csv"
# 1. Standard GC Benchmark
echo "🔵 PHASE 1: Standard GC"
build_binary "none"
start_services_traced
run_load
analyze_logs "Standard"
"$PROJECT_ROOT/scripts/stop-dev.sh"
sleep 5
# 2. GreenteaGC Benchmark
echo "🟢 PHASE 2: GreenteaGC"
build_binary "greenteagc"
start_services_traced
run_load
analyze_logs "GreenteaGC"
"$PROJECT_ROOT/scripts/stop-dev.sh"
echo "✅ Benchmarking complete! Summary saved to gc_benchmark_summary.csv"
cat "$PROJECT_ROOT/gc_benchmark_summary.csv" | column -t -s,