summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-06-16 23:15:31 +0300
committerPaul Buetow <paul@buetow.org>2025-06-16 23:15:31 +0300
commit7bc889acb28d8613944551d2129f0d9a7b65ecc3 (patch)
treef13d958ab7e12915651de63a45f204d7ba698048
parenta3c29db4df8650b5c6d9ae987c23d88ab606dd45 (diff)
Refactor PBO to PGO with true Profile-Guided Optimization
- Rename PBO (Profile-Based) to PGO (Performance Guided Optimization) - Implement true PGO using Go's -pgo compiler flag - Refactor script into maintainable functions: - setup_environment(): Initialize paths and variables - create_test_file(): Generate 100MB test file with 1M lines - build_baseline(): Build version without PGO optimizations - collect_training_data(): Generate CPU profiles for training - build_pgo_optimized(): Build with -pgo flag using training profile - run_pgo_performance_test(): Profile PGO-optimized version - run_performance_comparison(): Compare baseline vs PGO performance - generate_detailed_analysis(): Create comprehensive profile analysis - cleanup(): Remove temporary files - show_summary(): Display results and process summary - Update Makefile target from 'pbo' to 'pgo' - Update .gitignore patterns for PGO temporary files - Update CLAUDE.md documentation for new PGO process - Remove git stash dependencies for simpler automation - Generate before/after performance comparison reports 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
-rw-r--r--.gitignore7
-rw-r--r--CLAUDE.md18
-rw-r--r--Makefile8
-rwxr-xr-xscripts/pbo.sh113
-rwxr-xr-xscripts/pgo.sh159
5 files changed, 176 insertions, 129 deletions
diff --git a/.gitignore b/.gitignore
index 89c6501..88674e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,7 +18,8 @@ id_rsa
id_rsa.pub
ssh_host_key
-# PBO (Profile-Based Optimization) temporary files
-scripts/pbo_*.prof
-scripts/pbo_report.txt
+# PGO (Performance Guided Optimization) temporary files
+scripts/pgo_*.prof
+scripts/pgo_report.txt
scripts/test_100mb.txt
+dgrep_pgo
diff --git a/CLAUDE.md b/CLAUDE.md
index 753b3bf..e2353af 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -44,18 +44,18 @@ make lint
### Performance Optimization
```bash
-# Run Profile-Based Optimization (PBO) for dgrep
-make pbo
+# Run Performance Guided Optimization (PGO) for dgrep
+make pgo
-# This target will:
+# This implements true PGO using Go's -pgo compiler flag:
# - Create test file (100MB with 1M lines) in scripts/ if needed
-# - Run baseline profiling (CPU and memory)
-# - Run performance benchmarks
-# - Generate optimized profiles in scripts/ directory
-# - Create detailed comparison report (scripts/pbo_report.txt)
-# - Show key optimizations implemented
+# - Build baseline version without PGO
+# - Collect CPU profile for training data
+# - Rebuild dgrep with -pgo flag using the training profile
+# - Compare baseline vs PGO-optimized performance (5 iterations each)
+# - Generate detailed before/after analysis report (scripts/pgo_report.txt)
#
-# All PBO files are organized in scripts/ directory to keep project root clean
+# All PGO files are organized in scripts/ directory to keep project root clean
```
### Installation
diff --git a/Makefile b/Makefile
index d47df58..ef6cffa 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ help:
@echo " vet - Run go vet on all packages"
@echo " lint - Run golint on all packages"
@echo " install - Install all binaries to \$$GOPATH/bin"
- @echo " pbo - Run Profile-Based Optimization for dgrep"
+ @echo " pgo - Run Performance Guided Optimization for dgrep"
@echo ""
@echo "Individual binary targets:"
@echo " dserver, dcat, dgrep, dmap, dtail, dtailhealth"
@@ -63,6 +63,6 @@ test:
set -e; find . -name '*_test.go' | while read file; do dirname $$file; done | \
sort -u | while read dir; do ${GO} test -tags '${GO_TAGS}' --race -v -failfast $$dir || exit 2; done
-# Profile-Based Optimization (PBO) target for dgrep
-pbo: clean build
- @./scripts/pbo.sh
+# Performance Guided Optimization (PGO) target for dgrep
+pgo: clean build
+ @./scripts/pgo.sh
diff --git a/scripts/pbo.sh b/scripts/pbo.sh
deleted file mode 100755
index 909d28a..0000000
--- a/scripts/pbo.sh
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/bin/bash
-
-# Profile-Based Optimization (PBO) script for dgrep
-# This script automates the complete PBO process including baseline testing,
-# optimization application, and performance comparison
-
-set -e
-
-# Get the directory where this script is located
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-# Get the project root directory (parent of scripts)
-PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
-
-# Change to project root to run commands
-cd "$PROJECT_ROOT"
-
-# Define paths for all PBO files in scripts directory
-PBO_DIR="$SCRIPT_DIR"
-TEST_FILE="$PBO_DIR/test_100mb.txt"
-BASELINE_CPU_PROF="$PBO_DIR/pbo_baseline_cpu.prof"
-BASELINE_MEM_PROF="$PBO_DIR/pbo_baseline_mem.prof"
-OPTIMIZED_CPU_PROF="$PBO_DIR/pbo_optimized_cpu.prof"
-OPTIMIZED_MEM_PROF="$PBO_DIR/pbo_optimized_mem.prof"
-REPORT_FILE="$PBO_DIR/pbo_report.txt"
-
-echo "=== Starting Profile-Based Optimization (PBO) for dgrep ==="
-echo "Working directory: $PROJECT_ROOT"
-echo "PBO files location: $PBO_DIR"
-
-# 1. Create test file if needed
-echo "1. Creating test file if needed..."
-if [ ! -f "$TEST_FILE" ]; then
- echo "Creating 100MB test file with 1M lines..."
- for i in $(seq 1 1000000); do
- echo "$i: This is a test line with INFO level logging and some extra content to make it realistic"
- done > "$TEST_FILE"
-fi
-
-# 2. Run baseline performance test (assumes current state is baseline)
-echo "2. Running baseline performance test..."
-echo " - Generating CPU profile (baseline)..."
-./dgrep --plain -regex "INFO" -files "$TEST_FILE" -cpuprofile "$BASELINE_CPU_PROF" -memprofile "$BASELINE_MEM_PROF" > /dev/null
-
-echo " - Analyzing baseline profiles..."
-echo " CPU Profile (baseline):" > "$REPORT_FILE"
-go tool pprof -top "$BASELINE_CPU_PROF" | head -10 >> "$REPORT_FILE"
-echo " Memory Profile (baseline):" >> "$REPORT_FILE"
-go tool pprof -top "$BASELINE_MEM_PROF" | head -10 >> "$REPORT_FILE"
-
-# 3. Run performance benchmark
-echo "3. Running performance benchmark (3 iterations)..."
-echo " Baseline timings:" >> "$REPORT_FILE"
-for i in 1 2 3; do
- echo " Iteration $i:"
- (time ./dgrep --plain -regex "INFO" -files "$TEST_FILE" > /dev/null) 2>&1 | grep real >> "$REPORT_FILE"
-done
-
-# 4. Note optimizations (already implemented in code)
-echo "4. PBO optimizations are already implemented in the code"
-echo " - Timer allocation reduction (reusable timers)"
-echo " - I/O operation optimization (bulk writes, pre-allocated buffers)"
-echo " - Memory allocation improvements (buffer pooling)"
-
-# 5. Run optimized performance test
-echo "5. Running optimized performance test..."
-echo " - Generating CPU profile (optimized)..."
-./dgrep --plain -regex "INFO" -files "$TEST_FILE" -cpuprofile "$OPTIMIZED_CPU_PROF" -memprofile "$OPTIMIZED_MEM_PROF" > /dev/null
-
-echo " - Analyzing optimized profiles..."
-echo " CPU Profile (optimized):" >> "$REPORT_FILE"
-go tool pprof -top "$OPTIMIZED_CPU_PROF" | head -10 >> "$REPORT_FILE"
-echo " Memory Profile (optimized):" >> "$REPORT_FILE"
-go tool pprof -top "$OPTIMIZED_MEM_PROF" | head -10 >> "$REPORT_FILE"
-
-# 6. Run optimized benchmark
-echo "6. Running optimized benchmark (3 iterations)..."
-echo " Optimized timings:" >> "$REPORT_FILE"
-for i in 1 2 3; do
- echo " Iteration $i:"
- (time ./dgrep --plain -regex "INFO" -files "$TEST_FILE" > /dev/null) 2>&1 | grep real >> "$REPORT_FILE"
-done
-
-# 7. Generate comparison report
-echo "7. Generating comparison report..."
-echo "=== PROFILE-BASED OPTIMIZATION REPORT ===" >> "$REPORT_FILE"
-echo "Baseline memory usage:" >> "$REPORT_FILE"
-go tool pprof -top "$BASELINE_MEM_PROF" | grep "Showing nodes" >> "$REPORT_FILE" || echo "N/A" >> "$REPORT_FILE"
-echo "Optimized memory usage:" >> "$REPORT_FILE"
-go tool pprof -top "$OPTIMIZED_MEM_PROF" | grep "Showing nodes" >> "$REPORT_FILE" || echo "N/A" >> "$REPORT_FILE"
-echo "Baseline CPU samples:" >> "$REPORT_FILE"
-go tool pprof -top "$BASELINE_CPU_PROF" | grep "Total samples" >> "$REPORT_FILE" || echo "N/A" >> "$REPORT_FILE"
-echo "Optimized CPU samples:" >> "$REPORT_FILE"
-go tool pprof -top "$OPTIMIZED_CPU_PROF" | grep "Total samples" >> "$REPORT_FILE" || echo "N/A" >> "$REPORT_FILE"
-
-# 8. Summary
-echo "=== PBO Complete! ==="
-echo "Results saved to: $REPORT_FILE"
-echo "Profile files generated:"
-echo " - $BASELINE_CPU_PROF"
-echo " - $BASELINE_MEM_PROF"
-echo " - $OPTIMIZED_CPU_PROF"
-echo " - $OPTIMIZED_MEM_PROF"
-echo ""
-echo "Test file location: $TEST_FILE"
-echo ""
-echo "Key improvements implemented:"
-echo " ✓ Timer allocation reduction (eliminated time.After() calls)"
-echo " ✓ I/O operation optimization (bulk writes vs byte-by-byte)"
-echo " ✓ Memory allocation improvements (buffer pooling, pre-allocation)"
-echo ""
-
-# Show summary from report
-tail -20 "$REPORT_FILE" \ No newline at end of file
diff --git a/scripts/pgo.sh b/scripts/pgo.sh
new file mode 100755
index 0000000..a590313
--- /dev/null
+++ b/scripts/pgo.sh
@@ -0,0 +1,159 @@
+#!/bin/bash
+
+# Performance Guided Optimization (PGO) script for dgrep
+# This script implements true PGO using Go's -pgo compiler flag:
+# 1. Build baseline version
+# 2. Generate CPU profile for training
+# 3. Rebuild with PGO using the profile
+# 4. Compare before/after performance
+
+set -e
+
+# Global variables
+setup_environment() {
+ # Get the directory where this script is located
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ # Get the project root directory (parent of scripts)
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
+
+ # Change to project root to run commands
+ cd "$PROJECT_ROOT"
+
+ # Define paths for all PGO files in scripts directory
+ PGO_DIR="$SCRIPT_DIR"
+ TEST_FILE="$PGO_DIR/test_100mb.txt"
+ BASELINE_CPU_PROF="$PGO_DIR/pgo_baseline_cpu.prof"
+ BASELINE_MEM_PROF="$PGO_DIR/pgo_baseline_mem.prof"
+ TRAINING_PROF="$PGO_DIR/pgo_training.prof"
+ OPTIMIZED_CPU_PROF="$PGO_DIR/pgo_optimized_cpu.prof"
+ OPTIMIZED_MEM_PROF="$PGO_DIR/pgo_optimized_mem.prof"
+ REPORT_FILE="$PGO_DIR/pgo_report.txt"
+
+ echo "=== Starting Profile Guided Optimization (PGO) for dgrep ==="
+ echo "Working directory: $PROJECT_ROOT"
+ echo "PGO files location: $PGO_DIR"
+}
+
+create_test_file() {
+ echo "1. Creating test file if needed..."
+ if [ ! -f "$TEST_FILE" ]; then
+ echo "Creating 100MB test file with 1M lines..."
+ for i in $(seq 1 1000000); do
+ echo "$i: This is a test line with INFO level logging and some extra content to make it realistic"
+ done > "$TEST_FILE"
+ fi
+}
+
+build_baseline() {
+ echo "2. Building baseline version (without PGO)..."
+ # Clean any existing binaries
+ rm -f dgrep dgrep_pgo dcat dmap dtail dserver dtailhealth
+ go build -tags '' -o dgrep ./cmd/dgrep/main.go
+}
+
+collect_training_data() {
+ echo "3. Running baseline performance test and collecting training profile..."
+ echo " - Generating baseline CPU and memory profiles..."
+ ./dgrep --plain -regex "INFO" -files "$TEST_FILE" -cpuprofile "$BASELINE_CPU_PROF" -memprofile "$BASELINE_MEM_PROF" > /dev/null
+
+ echo " - Collecting training profile for PGO..."
+ ./dgrep --plain -regex "INFO" -files "$TEST_FILE" -cpuprofile "$TRAINING_PROF" > /dev/null
+}
+
+build_pgo_optimized() {
+ echo "4. Building PGO-optimized version using training profile..."
+ go build -tags '' -pgo="$TRAINING_PROF" -o dgrep_pgo ./cmd/dgrep/main.go
+}
+
+run_pgo_performance_test() {
+ echo "5. Running PGO-optimized performance test..."
+ echo " - Generating optimized CPU and memory profiles..."
+ ./dgrep_pgo --plain -regex "INFO" -files "$TEST_FILE" -cpuprofile "$OPTIMIZED_CPU_PROF" -memprofile "$OPTIMIZED_MEM_PROF" > /dev/null
+}
+
+run_performance_comparison() {
+ echo "6. Running performance comparison..."
+ echo "=== PROFILE GUIDED OPTIMIZATION REPORT ===" > "$REPORT_FILE"
+ echo "Generated: $(date)" >> "$REPORT_FILE"
+ echo "" >> "$REPORT_FILE"
+
+ echo "BASELINE (without PGO):" >> "$REPORT_FILE"
+ echo "Baseline performance (5 iterations):" >> "$REPORT_FILE"
+ for i in 1 2 3 4 5; do
+ echo " Iteration $i:"
+ { time ./dgrep --plain -regex "INFO" -files "$TEST_FILE" > /dev/null; } 2>&1 | grep real >> "$REPORT_FILE"
+ done
+
+ echo "" >> "$REPORT_FILE"
+ echo "PGO-OPTIMIZED:" >> "$REPORT_FILE"
+ echo "PGO-optimized performance (5 iterations):" >> "$REPORT_FILE"
+ for i in 1 2 3 4 5; do
+ echo " Iteration $i:"
+ { time ./dgrep_pgo --plain -regex "INFO" -files "$TEST_FILE" > /dev/null; } 2>&1 | grep real >> "$REPORT_FILE"
+ done
+}
+
+generate_detailed_analysis() {
+ echo "7. Adding detailed profile analysis..."
+ echo "" >> "$REPORT_FILE"
+ echo "DETAILED ANALYSIS:" >> "$REPORT_FILE"
+ echo "" >> "$REPORT_FILE"
+ echo "Baseline CPU Profile:" >> "$REPORT_FILE"
+ go tool pprof -top "$BASELINE_CPU_PROF" | head -10 >> "$REPORT_FILE"
+ echo "" >> "$REPORT_FILE"
+ echo "PGO-Optimized CPU Profile:" >> "$REPORT_FILE"
+ go tool pprof -top "$OPTIMIZED_CPU_PROF" | head -10 >> "$REPORT_FILE"
+ echo "" >> "$REPORT_FILE"
+ echo "Baseline Memory Profile:" >> "$REPORT_FILE"
+ go tool pprof -top "$BASELINE_MEM_PROF" | head -10 >> "$REPORT_FILE"
+ echo "" >> "$REPORT_FILE"
+ echo "PGO-Optimized Memory Profile:" >> "$REPORT_FILE"
+ go tool pprof -top "$OPTIMIZED_MEM_PROF" | head -10 >> "$REPORT_FILE"
+}
+
+cleanup() {
+ echo "8. Cleaning up..."
+ rm -f dgrep_pgo
+}
+
+show_summary() {
+ echo "=== PGO Complete! ==="
+ echo "Results saved to: $REPORT_FILE"
+ echo "Profile files generated:"
+ echo " - Baseline: $BASELINE_CPU_PROF, $BASELINE_MEM_PROF"
+ echo " - Training: $TRAINING_PROF"
+ echo " - Optimized: $OPTIMIZED_CPU_PROF, $OPTIMIZED_MEM_PROF"
+ echo ""
+ echo "Test file location: $TEST_FILE"
+ echo ""
+ echo "PGO Process:"
+ echo " ✓ Built baseline version without PGO"
+ echo " ✓ Collected CPU profile for training"
+ echo " ✓ Rebuilt with Go's -pgo flag using training profile"
+ echo " ✓ Compared baseline vs PGO-optimized performance"
+ echo ""
+
+ # Show performance comparison from report
+ echo "=== Performance Comparison ==="
+ echo "Check $REPORT_FILE for detailed before/after comparison"
+ grep -A 20 "BASELINE (without PGO)" "$REPORT_FILE" | head -10
+ echo "..."
+ grep -A 20 "PGO-OPTIMIZED" "$REPORT_FILE" | head -10
+}
+
+# Main execution flow
+main() {
+ setup_environment
+ create_test_file
+ build_baseline
+ collect_training_data
+ build_pgo_optimized
+ run_pgo_performance_test
+ run_performance_comparison
+ generate_detailed_analysis
+ cleanup
+ show_summary
+}
+
+# Run the main function
+main "$@" \ No newline at end of file