From shell-routines
Profile a slow-but-correct bash script: measure a baseline, trace with xtrace timing to find the hotspot, apply shell-specific optimisations, and benchmark the result. Use when a script works correctly but runs too slowly, or to measure/compare execution speed ("profile this script", "why is my script slow", "find the bottleneck"). For runtime errors use shell-debugging; for quality review use shell-review.
How this skill is triggered — by the user, by Claude, or both
Slash command
/shell-routines:shell-profilingThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guides systematic performance profiling of bash scripts to identify bottlenecks and apply targeted optimisations.
Guides systematic performance profiling of bash scripts to identify bottlenecks and apply targeted optimisations.
This skill handles performance problems -- scripts that work correctly but run too slowly. It covers:
This skill does not cover:
shell-debuggingshell-reviewshell-best-practicesThe profiling cycle is: measure the original, instrument a temporary copy to diagnose, discard the copy, apply fixes to the original, benchmark the result. Never leave profiling instrumentation in the target script.
Before profiling, decide what acceptable performance looks like (e.g., "under 5 seconds" or "twice as fast"). This prevents over-optimisation and gives a clear stopping condition.
Run the original script with time to establish a baseline. No modifications to the script:
time bash script.sh args
For per-section granularity, use EPOCHREALTIME inside the script (add temporarily, remove after measurement). See references/profiling-tools.md for all timing methods and their trade-offs.
Create a temporary copy of the script and add xtrace instrumentation to it. The original script remains untouched:
cp script.sh /tmp/script.profiling.sh
Insert after the shebang and set lines in the copy:
exec 42>/tmp/trace.log
BASH_XTRACEFD=42
PS4='+ ${EPOCHREALTIME} ${BASH_SOURCE}:${LINENO} ${FUNCNAME[0]:-main} '
set -x
Run the instrumented copy, then discard it. See references/profiling-tools.md for BASH_XTRACEFD setup and capture patterns.
Process the trace output to find the lines consuming the most time. Use scripts/trace-aggregate.sh for deterministic aggregation:
scripts/trace-aggregate.sh /tmp/trace.log
Output shows cumulative time per source location with call counts, sorted by descending time.
Look for locations with the highest cumulative time and call counts, particularly tight loops, subshell invocations, or external command calls.
When the hotspot involves system calls or I/O, use deeper analysis tools. These run against the original script without modification:
# Syscall summary (Linux)
strace -c -f bash script.sh
# Detailed resource usage
/usr/bin/time -v bash script.sh
See references/profiling-tools.md for platform-specific alternatives (macOS: dtruss, sample, Instruments).
Apply fixes to the original script (not the instrumented copy). Consult references/optimisation-patterns.md for shell-specific fixes:
$(cmd) with parameter expansionlastpipe, pre-allocated arraysMeasure the improvement statistically against the original baseline:
# With hyperfine (recommended)
hyperfine 'bash script_before.sh' 'bash script_after.sh'
# With bench.sh (no hyperfine required)
scripts/bench.sh -r 10 -w 1 -- bash script_before.sh
scripts/bench.sh -r 10 -w 1 -- bash script_after.sh
Discard the first run (warm-up), compare median not mean.
If the result still misses the target set in step 1, return to step 3 with the next hotspot; stop once the target is met or all viable patterns are exhausted.
Present a before/after comparison:
Clean up temporary files (/tmp/trace.log, /tmp/script.profiling.sh).
references/profiling-tools.md -- Comprehensive catalogue of timing, tracing, syscall, and benchmarking tools with syntax examples, output interpretation, and platform availabilityreferences/optimisation-patterns.md -- Shell-specific performance patterns with before/after code snippets, covering subshells, builtins, I/O, loops, and string processingAlways read all references, scripts, and examples before producing output.
scripts/trace-aggregate.sh -- Aggregates xtrace timestamps into cumulative per-line timings with call counts. Usage: trace-aggregate.sh <trace-file> [top-n]scripts/bench.sh -- Manual benchmark harness with warm-up runs, median/min/max/spread statistics. Usage: bench.sh [-r runs] [-w warmup] [--] <command...>examples/profile-session.md -- End-to-end walkthrough: profiling a slow log-processing script from baseline measurement through hotspot identification, optimisation, and benchmarkingshell-debugging -- For scripts that produce errors or incorrect output (profiling assumes the script works correctly)shell-best-practices -- General writing standards, quoting, error handling (apply alongside performance optimisations)shell-review -- Quality assessment after optimisation is completeshell-architect agent -- Architectural decisions affecting performance (batch vs individual processing, parallelism strategy, data flow)Blocks Edit/Write/Bash actions until Claude investigates importers, data schemas, and user instructions. Improves output quality by forcing concrete facts before edits.
npx claudepluginhub objctp/shell-routines