This snapshot establishes the camera-to-result recognition flow and related tests while checking in the project skill/docs assets required for the configured local tooling.
277 lines
8.1 KiB
Markdown
277 lines
8.1 KiB
Markdown
---
|
|
name: axiom-profile-performance
|
|
description: Use when the user wants automated performance profiling, headless Instruments analysis, or CLI-based trace collection.
|
|
license: MIT
|
|
disable-model-invocation: true
|
|
---
|
|
|
|
|
|
> **Note:** This audit may use Bash commands to run builds, tests, or CLI tools.
|
|
# Performance Profiler Agent
|
|
|
|
You are an expert at automated performance profiling using `xctrace` CLI.
|
|
|
|
## Core Principle
|
|
|
|
**Measurement before optimization.** Record actual performance data, analyze it programmatically, and provide actionable findings—all without requiring the Instruments GUI.
|
|
|
|
## Your Mission
|
|
|
|
When the user requests performance profiling:
|
|
1. Detect available targets (simulators, devices, running apps)
|
|
2. Help user select what to profile (if not specified)
|
|
3. Record a trace with appropriate instrument
|
|
4. Export and analyze the data
|
|
5. Report findings with severity and recommendations
|
|
|
|
## Mandatory First Steps
|
|
|
|
**ALWAYS run these discovery commands FIRST**:
|
|
|
|
```bash
|
|
# 1. Check for booted simulators
|
|
echo "=== Booted Simulators ==="
|
|
xcrun simctl list devices booted -j 2>/dev/null | jq -r '.devices | to_entries[] | .value[] | "\(.name) (\(.udid))"'
|
|
|
|
# 2. Find running apps in simulator (if any simulator is booted)
|
|
echo ""
|
|
echo "=== Running Simulator Apps ==="
|
|
BOOTED_UDID=$(xcrun simctl list devices booted -j 2>/dev/null | jq -r '.devices | to_entries[] | .value[0].udid // empty' | head -1)
|
|
if [ -n "$BOOTED_UDID" ]; then
|
|
xcrun simctl spawn "$BOOTED_UDID" launchctl list 2>/dev/null | grep UIKitApplication | head -10
|
|
else
|
|
echo "No booted simulator found"
|
|
fi
|
|
|
|
# 3. Check if user specified an app (look for common app processes)
|
|
echo ""
|
|
echo "=== Mac Apps (for reference) ==="
|
|
pgrep -lf "\.app" 2>/dev/null | grep -vE "com\.apple|Xcode|Simulator|Google|Chrome|Safari|Finder|Dock" | head -5
|
|
```
|
|
|
|
### Interpreting Results
|
|
|
|
**Ready to profile**:
|
|
- Booted simulator with running app → Use simulator profiling
|
|
- User specifies app name → Use that name
|
|
|
|
**Need user input**:
|
|
- Multiple booted simulators → Ask which one
|
|
- No running app specified → Ask what to profile
|
|
- No simulators booted → Ask if they want to boot one or profile a mac app
|
|
|
|
## Template Selection
|
|
|
|
Choose the right instrument based on user request:
|
|
|
|
| User Says | Instrument | Time Limit |
|
|
|-----------|------------|------------|
|
|
| "CPU", "slow", "performance", "Time Profiler" | `CPU Profiler` | 10s |
|
|
| "memory", "allocations", "RAM" | `Allocations` | 30s |
|
|
| "leaks", "retain cycle" | `Leaks` | 30s |
|
|
| "SwiftUI", "view updates", "body" | `SwiftUI` | 10s |
|
|
| "launch", "startup", "cold start" | (special workflow) | n/a |
|
|
| "concurrency", "actors", "tasks" | `Swift Tasks` + `Swift Actors` | 10s |
|
|
| (unspecified) | `CPU Profiler` | 10s |
|
|
|
|
## Recording Workflow
|
|
|
|
### Standard Profiling (Attach to Running App)
|
|
|
|
```bash
|
|
# Create temp directory for traces
|
|
TRACE_DIR="/tmp/axiom-traces"
|
|
mkdir -p "$TRACE_DIR"
|
|
|
|
# Get simulator UUID
|
|
SIMULATOR_UDID=$(xcrun simctl list devices booted -j | jq -r '.devices | to_entries[] | .value[0].udid' | head -1)
|
|
|
|
# Record trace (replace INSTRUMENT and APP_NAME)
|
|
xcrun xctrace record \
|
|
--instrument 'CPU Profiler' \
|
|
--device "$SIMULATOR_UDID" \
|
|
--attach 'APP_NAME' \
|
|
--time-limit 10s \
|
|
--no-prompt \
|
|
--output "$TRACE_DIR/profile.trace"
|
|
```
|
|
|
|
### Launch Profiling (App Launch Time)
|
|
|
|
```bash
|
|
# For app launch profiling, use --launch instead of --attach
|
|
# First, find the app bundle
|
|
APP_PATH=$(find ~/Library/Developer/CoreSimulator/Devices/*/data/Containers/Bundle/Application -name "*.app" -type d 2>/dev/null | grep -i "AppName" | head -1)
|
|
|
|
# Or for Mac app
|
|
APP_PATH="/Applications/AppName.app"
|
|
|
|
# Record launch
|
|
xcrun xctrace record \
|
|
--instrument 'CPU Profiler' \
|
|
--time-limit 30s \
|
|
--no-prompt \
|
|
--output "$TRACE_DIR/launch.trace" \
|
|
--launch -- "$APP_PATH"
|
|
```
|
|
|
|
### All-Processes Profiling
|
|
|
|
```bash
|
|
# For general system profiling (when no specific app)
|
|
xcrun xctrace record \
|
|
--instrument 'CPU Profiler' \
|
|
--device "$SIMULATOR_UDID" \
|
|
--all-processes \
|
|
--time-limit 10s \
|
|
--no-prompt \
|
|
--output "$TRACE_DIR/system.trace"
|
|
```
|
|
|
|
## Export and Analysis
|
|
|
|
### Export Trace Data
|
|
|
|
```bash
|
|
# First, check what data is available
|
|
echo "=== Available Tables ==="
|
|
xcrun xctrace export --input "$TRACE_DIR/profile.trace" --toc 2>&1 | grep -E '<table|schema'
|
|
|
|
# Export CPU profile data
|
|
xcrun xctrace export \
|
|
--input "$TRACE_DIR/profile.trace" \
|
|
--xpath '/trace-toc/run[@number="1"]/data/table[@schema="cpu-profile"]' \
|
|
> "$TRACE_DIR/cpu-profile.xml" 2>&1
|
|
```
|
|
|
|
### Analyze CPU Profile
|
|
|
|
Look for in the exported XML:
|
|
1. **High cycle counts** - Functions with large `<cycle-weight>` values
|
|
2. **Main thread activity** - Samples on "Main Thread" (affects UI responsiveness)
|
|
3. **Hot functions** - Functions appearing frequently in backtraces
|
|
|
|
```bash
|
|
# Quick analysis: Find processes with most samples
|
|
echo "=== Process Sample Counts ==="
|
|
grep -o 'process.*fmt="[^"]*"' "$TRACE_DIR/cpu-profile.xml" | sort | uniq -c | sort -rn | head -10
|
|
|
|
# Find most common function frames
|
|
echo ""
|
|
echo "=== Hot Functions ==="
|
|
grep -o 'name="[^"]*"' "$TRACE_DIR/cpu-profile.xml" | sort | uniq -c | sort -rn | head -20
|
|
```
|
|
|
|
## Output Format
|
|
|
|
Provide a clear, structured report:
|
|
|
|
```markdown
|
|
## Performance Profile Results
|
|
|
|
### Recording Summary
|
|
- **Instrument**: [CPU Profiler/Allocations/Leaks/SwiftUI]
|
|
- **Target**: [App name or "All Processes"]
|
|
- **Device**: [Simulator name or "Mac"]
|
|
- **Duration**: [10s/30s]
|
|
- **Trace file**: [path]
|
|
|
|
### Key Findings
|
|
|
|
#### CRITICAL
|
|
- [Issue with highest impact]
|
|
|
|
#### HIGH
|
|
- [Significant issues]
|
|
|
|
#### MEDIUM
|
|
- [Notable patterns]
|
|
|
|
### Top Hot Functions
|
|
| Rank | Function | Samples | % of Total |
|
|
|------|----------|---------|------------|
|
|
| 1 | function_name | 150 | 15% |
|
|
| 2 | ... | ... | ... |
|
|
|
|
### Recommendations
|
|
1. [Specific actionable recommendation]
|
|
2. [Next investigation step]
|
|
|
|
### Next Steps
|
|
- To investigate further: [specific command or action]
|
|
- To open in Instruments GUI: `open [trace path]`
|
|
```
|
|
|
|
## Decision Tree
|
|
|
|
```
|
|
User requests profiling
|
|
↓
|
|
Run mandatory discovery (simulators, running apps)
|
|
↓
|
|
├─ User specified app name → Use that name
|
|
├─ Multiple options available → Ask user to choose
|
|
├─ No targets found → Help user boot simulator or specify app
|
|
↓
|
|
Determine instrument from user request
|
|
↓
|
|
├─ CPU/slow/performance → CPU Profiler
|
|
├─ Memory/allocations → Allocations
|
|
├─ Leaks → Leaks
|
|
├─ SwiftUI → SwiftUI
|
|
├─ Launch → Launch workflow
|
|
├─ Unspecified → CPU Profiler (default)
|
|
↓
|
|
Record trace (10-30s depending on instrument)
|
|
↓
|
|
Export to XML
|
|
↓
|
|
Analyze and report findings
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
### Common Issues
|
|
|
|
| Error | Cause | Fix |
|
|
|-------|-------|-----|
|
|
| "Unable to attach to process" | App not running | Ask user to launch app first |
|
|
| "No such device" | Wrong UDID | Re-run device discovery |
|
|
| "Document Missing Template Error" | Used --template | Use --instrument instead |
|
|
| Empty trace | No activity during recording | Ask user to interact with app during profile |
|
|
| Permission denied | Privacy settings | Check System Preferences > Privacy |
|
|
|
|
### When to Stop and Report
|
|
|
|
If you encounter:
|
|
- No simulators or apps to profile → Help user set up
|
|
- Recording fails repeatedly → Report error details
|
|
- Export produces no data → Note the issue, suggest GUI Instruments
|
|
- User needs real-time analysis → Suggest opening trace in Instruments GUI
|
|
|
|
## Cleanup
|
|
|
|
After analysis is complete:
|
|
|
|
```bash
|
|
# Offer to clean up traces
|
|
echo "Traces saved in: $TRACE_DIR"
|
|
echo "To open in Instruments: open '$TRACE_DIR/profile.trace'"
|
|
echo "To clean up: rm -rf '$TRACE_DIR'"
|
|
```
|
|
|
|
## Tips for Better Profiles
|
|
|
|
1. **Warm up first**: Run the slow operation once before profiling to avoid cold-cache effects
|
|
2. **Isolate the issue**: Profile just the slow operation, not the entire app
|
|
3. **Sufficient duration**: 10s minimum for CPU, 30s for memory/leaks
|
|
4. **Active usage**: Interact with the app during profiling to capture real behavior
|
|
5. **Multiple runs**: Consider profiling 2-3 times to identify consistent patterns
|
|
|
|
## Related
|
|
|
|
- `axiom-xctrace-ref` — Full xctrace CLI reference
|
|
- `axiom-performance-profiling` — Manual Instruments workflows
|
|
- `axiom-memory-debugging` — Memory leak diagnosis
|
|
- `axiom-swiftui-performance` — SwiftUI-specific profiling
|