- Core library with SVG and PNG generation - CLI tool with generate and batch commands - Cross-platform path handling for Windows compatibility - Comprehensive test suite with integration tests
156 lines
5.8 KiB
Bash
Executable File
156 lines
5.8 KiB
Bash
Executable File
#!/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}" |