#!/bin/bash # Quick Memory Hotspot Validation Script # Usage: ./scripts/benchmark-hotspots.sh [baseline_dir] set -e # Colors GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' echo -e "${BLUE}🎯 Go Jdenticon Hotspot Validation${NC}" echo -e "${BLUE}=================================${NC}" BASELINE_DIR="${1:-./profiles/baseline}" TEMP_DIR="./profiles/temp_$(date +%s)" mkdir -p "$TEMP_DIR" # Function to run quick benchmark quick_benchmark() { local package=$1 local name=$2 echo -e "${BLUE}⚡ Quick benchmark: ${package}${NC}" go test -bench=BenchmarkGenerate -benchmem -count=3 "./${package}" > "${TEMP_DIR}/${name}_current.txt" 2>&1 } # Function to extract key metrics extract_metrics() { local file=$1 # Extract allocation metrics from benchmark output grep "BenchmarkGenerate" "$file" | \ awk '{ if (NF >= 5) { ns_per_op = $3 bytes_per_op = $4 allocs_per_op = $5 gsub(/ns\/op/, "", ns_per_op) gsub(/B\/op/, "", bytes_per_op) gsub(/allocs\/op/, "", allocs_per_op) print bytes_per_op "," allocs_per_op "," ns_per_op } }' | tail -1 } # Function to compare metrics compare_metrics() { local baseline_file=$1 local current_file=$2 local component=$3 if [ ! -f "$baseline_file" ]; then echo -e "${YELLOW}⚠️ No baseline found for ${component}${NC}" return fi baseline_metrics=$(extract_metrics "$baseline_file") current_metrics=$(extract_metrics "$current_file") if [ -z "$baseline_metrics" ] || [ -z "$current_metrics" ]; then echo -e "${RED}❌ Could not extract metrics for ${component}${NC}" return fi IFS=',' read -r baseline_bytes baseline_allocs baseline_ns <<< "$baseline_metrics" IFS=',' read -r current_bytes current_allocs current_ns <<< "$current_metrics" # Calculate percentage changes bytes_change=$(echo "scale=1; ($current_bytes - $baseline_bytes) * 100 / $baseline_bytes" | bc 2>/dev/null || echo "0") allocs_change=$(echo "scale=1; ($current_allocs - $baseline_allocs) * 100 / $baseline_allocs" | bc 2>/dev/null || echo "0") time_change=$(echo "scale=1; ($current_ns - $baseline_ns) * 100 / $baseline_ns" | bc 2>/dev/null || echo "0") echo -e "\n${BLUE}📊 ${component} Comparison:${NC}" echo -e " Memory: ${baseline_bytes} → ${current_bytes} B/op (${bytes_change}%)" echo -e " Allocations: ${baseline_allocs} → ${current_allocs} allocs/op (${allocs_change}%)" echo -e " Time: ${baseline_ns} → ${current_ns} ns/op (${time_change}%)" # Color code the results if (( $(echo "$bytes_change < -5" | bc -l 2>/dev/null || echo 0) )); then echo -e " Status: ${GREEN}🚀 Memory improvement!${NC}" elif (( $(echo "$bytes_change > 10" | bc -l 2>/dev/null || echo 0) )); then echo -e " Status: ${RED}⚠️ Memory regression${NC}" else echo -e " Status: ${YELLOW}📈 Within normal range${NC}" fi } # Main execution echo -e "${YELLOW}🔥 Running hotspot validation benchmarks...${NC}\n" # Run benchmarks for key components quick_benchmark "internal/engine" "engine" quick_benchmark "jdenticon" "full" echo -e "\n${BLUE}📈 Comparing with baseline...${NC}" # Compare with baseline if available if [ -d "$BASELINE_DIR" ]; then compare_metrics "${BASELINE_DIR}/engine_memory_results.txt" "${TEMP_DIR}/engine_current.txt" "Engine" compare_metrics "${BASELINE_DIR}/full_memory_results.txt" "${TEMP_DIR}/full_current.txt" "Full Library" else echo -e "${YELLOW}⚠️ No baseline directory found at: ${BASELINE_DIR}${NC}" echo -e "${BLUE}💡 Run memory-analysis.sh first to establish baseline${NC}" fi # Show current raw results echo -e "\n${BLUE}📋 Current Raw Results:${NC}" echo -e "${YELLOW}Engine Package:${NC}" grep "BenchmarkGenerate" "${TEMP_DIR}/engine_current.txt" | head -5 || echo "No results" echo -e "\n${YELLOW}Full Library:${NC}" grep "BenchmarkGenerate" "${TEMP_DIR}/full_current.txt" | head -5 || echo "No results" # Quick hotspot check echo -e "\n${BLUE}🔍 Quick Hotspot Status Check:${NC}" # Check if we're within expected performance bounds engine_metrics=$(extract_metrics "${TEMP_DIR}/engine_current.txt") if [ -n "$engine_metrics" ]; then IFS=',' read -r bytes allocs ns <<< "$engine_metrics" echo -e "Current Performance:" echo -e " Memory: ${bytes} B/op" echo -e " Allocations: ${allocs} allocs/op" echo -e " Time: ${ns} ns/op" # Check against known hotspot targets if (( $(echo "$bytes > 6000" | bc -l 2>/dev/null || echo 0) )); then echo -e " ${RED}🔥 High memory usage - optimization needed${NC}" elif (( $(echo "$bytes < 3000" | bc -l 2>/dev/null || echo 0) )); then echo -e " ${GREEN}✅ Excellent memory efficiency${NC}" else echo -e " ${YELLOW}📊 Moderate memory usage${NC}" fi if (( $(echo "$allocs > 60" | bc -l 2>/dev/null || echo 0) )); then echo -e " ${RED}🔥 High allocation count - pooling opportunities${NC}" elif (( $(echo "$allocs < 30" | bc -l 2>/dev/null || echo 0) )); then echo -e " ${GREEN}✅ Efficient allocation pattern${NC}" else echo -e " ${YELLOW}📊 Moderate allocation count${NC}" fi fi echo -e "\n${BLUE}💡 Quick Commands:${NC}" echo -e " Set as new baseline: ${YELLOW}cp ${TEMP_DIR}/*_current.txt ${BASELINE_DIR}/${NC}" echo -e " Full analysis: ${YELLOW}./scripts/memory-analysis.sh${NC}" echo -e " Profile specific hotspot: ${YELLOW}go test -bench=BenchmarkGenerate -memprofile=temp.prof ./internal/engine && go tool pprof temp.prof${NC}" # Cleanup echo -e "\n${GREEN}✅ Hotspot validation completed${NC}" echo -e "${BLUE}📁 Temp results in: ${TEMP_DIR}${NC}"