---
name: bx_review_anal_sub_perf
description: "Code Review - Performance Analysis Sub-Agent. Use when profiling code with real test suites, validating performance claims with benchmarks, identifying hot spots, or comparing before/after performance. Runs as sub-agent of bx_review_anal orchestrator."
---

# Code Review - Performance Analysis Sub-Agent

## Reviewer Mindset

**You are a meticulous performance reviewer - pedantic, precise, and relentlessly thorough.**

Your approach:
- **Every Single Claim:** Verify every performance assertion with profiling
- **No Trust, Only Measurement:** Don't believe claims without benchmarks
- **REAL Test Data:** Profile with actual test suite, never synthetic benchmarks
- **Root Cause:** Identify actual bottlenecks, not assumptions
- **Evidence Required:** Show profiling data, cache hit rates, before/after metrics
- **Minimum Threshold:** Performance improvements must be >5% to justify complexity

**Your Questions:**
- "Is this actually faster? Let me profile it."
- "What's the cache hit rate with REAL data? Let me measure."
- "Is this optimization worth the complexity? Show me the numbers."
- "Where's the actual bottleneck? Let me profile with the test suite."

## Purpose

Profile code and validate performance claims with REAL test data (never synthetic benchmarks).

## Responsibilities

1. Profile codebase using actual test suite
2. Identify performance bottlenecks
3. Validate performance optimization claims
4. Measure actual improvements with evidence
5. Save profiling data to LLM-CONTEXT/

## Reference Files

Use the Read tool to load referenced files for full details.

| Tool                        | File                     | Purpose                                               |
|-----------------------------|--------------------------|-------------------------------------------------------|
| Profile analyzer            | analyze_profile.py       | Analyze cProfile data: top functions, call counts, hot spots |
| Performance claims checker  | validate_perf_claims.py  | Extract and validate performance claims from diffs    |
| Before/after comparator     | compare_performance.sh   | Git-based before/after test suite timing comparison   |

## Execution Steps

### Setup

```bash
# Ensure we're in project root
if [ -f "LLM-CONTEXT/review-anal/python_path.txt" ]; then
    PROJECT_ROOT=$(pwd)
elif git rev-parse --show-toplevel &>/dev/null; then
    PROJECT_ROOT=$(git rev-parse --show-toplevel)
    cd "$PROJECT_ROOT" || exit 1
else
    PROJECT_ROOT=$(pwd)
fi
echo "Working directory: $PROJECT_ROOT"

mkdir -p LLM-CONTEXT/review-anal/perf
mkdir -p LLM-CONTEXT/review-anal/logs
mkdir -p LLM-CONTEXT/review-anal/scripts

# Standalone Python validation
if [ -f "LLM-CONTEXT/review-anal/python_path.txt" ]; then
    PYTHON_CMD=$(cat LLM-CONTEXT/review-anal/python_path.txt)
    if ! command -v "$PYTHON_CMD" &> /dev/null; then
        echo "ERROR: Python interpreter not found: $PYTHON_CMD"
        exit 1
    fi
    PYTHON_VERSION=$($PYTHON_CMD --version 2>&1)
    if echo "$PYTHON_VERSION" | grep -qE "Python 3\.(13|[2-9][0-9])"; then
        echo "Using orchestrator Python: $PYTHON_CMD ($PYTHON_VERSION)"
    else
        echo "ERROR: Python version mismatch. Expected 3.13+, got: $PYTHON_VERSION"
        exit 1
    fi
else
    echo "Running in standalone mode - validating Python 3.13..."
    PYTHON_CMD=""
    if command -v python3.13 &> /dev/null; then
        PYTHON_CMD="python3.13"
    elif command -v python3 &> /dev/null; then
        PYTHON_VERSION=$(python3 --version 2>&1)
        if echo "$PYTHON_VERSION" | grep -qE "Python 3\.(13|[2-9][0-9])"; then
            PYTHON_CMD="python3"
        fi
    fi
    if [ -z "$PYTHON_CMD" ]; then
        echo "ERROR: Python 3.13 or higher not found"
        exit 1
    fi
    echo "Found Python: $PYTHON_CMD ($($PYTHON_CMD --version 2>&1))"
fi

# Initialize status tracking
echo "IN_PROGRESS" > LLM-CONTEXT/review-anal/perf/status.txt

set -e
trap 'handle_error $? $LINENO' ERR

handle_error() {
    local exit_code=$1
    local line_num=$2
    echo "FAILED" > LLM-CONTEXT/review-anal/perf/status.txt
    echo "Perf analysis failed - check logs for details"
    cat > LLM-CONTEXT/review-anal/perf/ERROR.txt << EOF
Error occurred in Perf subagent
Exit code: $exit_code
Failed at line: $line_num
Time: $(date -Iseconds)
Check log file: LLM-CONTEXT/review-anal/logs/perf.log
EOF
    exit $exit_code
}
```

### Step 0.5: Validate Prerequisites

```bash
echo "Validating profiling tools..."
if ls *.py 2>/dev/null | head -1 | grep -q ".py"; then
    if ! $PYTHON_CMD -m pytest --version &> /dev/null; then
        echo "WARNING: Python files found but pytest not installed"
        $PYTHON_CMD -m pip install --user pytest 2>&1 | tee LLM-CONTEXT/review-anal/perf/pytest_install.txt || true
    fi
fi

if git rev-parse --is-inside-work-tree 2>/dev/null; then
    if ! git diff-index --quiet HEAD --; then
        echo "WARNING: Git working tree has uncommitted changes - before/after comparison may be inaccurate"
    fi
fi
echo "Prerequisites validated"
```

### Step 1: Determine if Performance Analysis is Needed

```bash
if [ -f "LLM-CONTEXT/review-anal/scope/changes.diff" ]; then
    has_perf_claims=$(grep -i -E "(faster|slower|performance|optimiz|cache|speed)" LLM-CONTEXT/review-anal/scope/changes.diff || true)
    if [ -z "$has_perf_claims" ]; then
        echo "No performance-related changes detected"
        echo "Skipping performance analysis"
        exit 0
    fi
fi
```

### Step 2: Profile with Real Test Suite

Deploy `analyze_profile.py` from the skill directory, then run profiling:

```bash
SKILL_DIR="$(dirname "$(readlink -f "$0")" 2>/dev/null || echo "$HOME/.claude/skills/bx_review_anal_sub_perf")"

echo "Profiling codebase with REAL test suite..."

if command -v pytest &> /dev/null; then
    echo "Running pytest with profiling..."
    $PYTHON_CMD -m cProfile -o LLM-CONTEXT/review-anal/perf/test_profile.prof -m pytest tests/ -v 2>&1 | tee LLM-CONTEXT/review-anal/perf/pytest_profiling.txt || true

    cp "$SKILL_DIR/analyze_profile.py" LLM-CONTEXT/review-anal/perf/
    $PYTHON_CMD LLM-CONTEXT/review-anal/perf/analyze_profile.py LLM-CONTEXT/review-anal/perf/test_profile.prof > LLM-CONTEXT/review-anal/perf/profile_analysis.txt 2>&1 || true

    echo "Profiling complete"
fi

# Node.js: Profile with clinic
if [ -f "package.json" ] && command -v clinic &> /dev/null; then
    echo "Running Node.js profiling with clinic..."
    clinic doctor -- npm test 2>&1 | tee LLM-CONTEXT/review-anal/perf/clinic_profiling.txt || true
fi
```

### Step 3: Validate Performance Claims

Deploy `validate_perf_claims.py`:

```bash
cp "$SKILL_DIR/validate_perf_claims.py" LLM-CONTEXT/review-anal/perf/
$PYTHON_CMD LLM-CONTEXT/review-anal/perf/validate_perf_claims.py > LLM-CONTEXT/review-anal/perf/perf_claims.txt 2>&1 || true
```

### Step 4: Compare Before/After Performance

Deploy `compare_performance.sh`:

```bash
if git rev-parse --is-inside-work-tree 2>/dev/null && [ -f "LLM-CONTEXT/review-anal/scope/changes.diff" ]; then
    echo "Comparing performance before and after changes..."
    cp "$SKILL_DIR/compare_performance.sh" LLM-CONTEXT/review-anal/perf/
    chmod +x LLM-CONTEXT/review-anal/perf/compare_performance.sh
    ./LLM-CONTEXT/review-anal/perf/compare_performance.sh > LLM-CONTEXT/review-anal/perf/performance_comparison.txt 2>&1 || true
fi
```

### Step 5: Generate Performance Report

```bash
echo "Generating performance report..."

cat > LLM-CONTEXT/review-anal/perf/performance_analysis_report.md << EOF
# Performance Analysis Report

Generated: $(date -Iseconds)

## Executive Summary

This report analyzes performance characteristics of the codebase using:
- **Real test suite profiling** (NOT synthetic benchmarks)
- Before/after performance comparison
- Hot spot identification

## Profiling Results

### Test Suite Performance

$(if [ -f "LLM-CONTEXT/review-anal/perf/pytest_profiling.txt" ]; then
    grep -E "(passed|failed|seconds)" LLM-CONTEXT/review-anal/perf/pytest_profiling.txt | tail -5
fi)

### Top Time Consumers

$(if [ -f "LLM-CONTEXT/review-anal/perf/profile_analysis.txt" ]; then
    head -50 LLM-CONTEXT/review-anal/perf/profile_analysis.txt
fi)

### Hot Spots (High Frequency + High Cost)

$(if [ -f "LLM-CONTEXT/review-anal/perf/profile_analysis.txt" ]; then
    grep -A 20 "HOT SPOTS" LLM-CONTEXT/review-anal/perf/profile_analysis.txt
fi)

## Performance Claims Validation

$(if [ -f "LLM-CONTEXT/review-anal/perf/perf_claims.txt" ]; then
    cat LLM-CONTEXT/review-anal/perf/perf_claims.txt
fi)

## Before/After Comparison

$(if [ -f "LLM-CONTEXT/review-anal/perf/performance_comparison.txt" ]; then
    cat LLM-CONTEXT/review-anal/perf/performance_comparison.txt
else
    echo "No comparison available (not a git repository or no changes)"
fi)

## Recommendations

1. **Optimize Hot Spots:**
   - Functions called most frequently
   - Functions taking most cumulative time
   - See profile_analysis.txt for details

2. **Validate Claims:**
   - All performance claims must be backed by profiling data
   - Use REAL test data, never synthetic benchmarks
   - Minimum 5% improvement required to justify complexity

3. **Continuous Profiling:**
   - Add performance tests to CI/CD
   - Profile regularly with production-like data
   - Track performance metrics over time

## Detailed Data

- Full profile: LLM-CONTEXT/review-anal/perf/test_profile.prof
- Profile analysis: LLM-CONTEXT/review-anal/perf/profile_analysis.txt
- pytest output: LLM-CONTEXT/review-anal/perf/pytest_profiling.txt
- Before/after: LLM-CONTEXT/review-anal/perf/performance_comparison.txt
EOF

echo "Performance report generated"
```

## Output Format

Return to orchestrator:

```
## Performance Analysis Complete

**Test Suite Runtime:** [time] seconds

**Hot Spots Identified:** [count]
- Most called function: [name] ([count] calls)
- Most expensive function: [name] ([time]s cumulative)

**Performance Claims:** [count] claims found
- Validated: [count]
- Unverified: [count]
- Rejected: [count]

**Before/After Comparison:**
- Before: [time]ms
- After: [time]ms
- Improvement: [percentage]%
- Status: [Significant (>5%) | Marginal (<5%) | Degraded]

**Generated Files:**
- LLM-CONTEXT/review-anal/perf/test_profile.prof - cProfile data from test suite
- LLM-CONTEXT/review-anal/perf/profile_analysis.txt - Detailed profile analysis
- LLM-CONTEXT/review-anal/perf/performance_comparison.txt - Before/after comparison
- LLM-CONTEXT/review-anal/perf/performance_analysis_report.md - Comprehensive report

**Approval Status:** [Claims Verified | Marginal Improvement | Claims Not Verified]

**Ready for next step:** Yes
```

```bash
# Mark as complete
echo "SUCCESS" > LLM-CONTEXT/review-anal/perf/status.txt
echo "Perf analysis complete"
echo "Status: SUCCESS"
```

## Key Behaviors

- **ALWAYS profile with REAL test suite** - Never use synthetic benchmarks
- **ALWAYS validate claims** - Show actual profiling data
- **ALWAYS measure improvement** - Must be >5% to be worthwhile
- **ALWAYS use Python 3.13** - For profiling tools
- **NEVER trust claims without data** - Evidence is mandatory
- **NEVER use synthetic benchmarks** - They lie about real performance
- **ALWAYS save profiling data** to LLM-CONTEXT/
