Complexity Optimizer
Find algorithmic complexity hotspots in a codebase and produce a structured report. Optionally implement low-risk optimizations after explicit consent.
When to Apply
Use this skill when the user asks to:
- Analyze, audit, scan, or review a codebase for performance hotspots or algorithmic complexity
- Find inefficient loops, nested iteration, N+1 queries, sort-in-loop, render-path recomputation
- Reduce complexity (e.g. O(n^2) → O(n log n) or O(n))
- "Give me a report" on a codebase's complexity profile
Do not use this skill for:
- Micro-optimizations on cold code paths
- Memory tuning (this skill targets time complexity, not allocation profiles)
- Code style refactoring unrelated to complexity
Workflow Overview
Baseline → Rank → Prove behavior → Optimize (opt-in) → Verify
↓ ↓ ↓
scanner prioritize hot rollback if
+ manual paths & large I/O tests regress
| Step |
Action |
Tool |
Risk |
| 1 |
Establish baseline: detect stack, test command, hot paths |
scripts/analyze_complexity.py + manual inspection |
read-only |
| 2 |
Rank opportunities by impact, separating algorithmic wins from constant-factor cleanup |
reasoning |
read-only |
| 3 |
Locate or add tests covering the function/component |
Read + test framework |
read-only |
| 4 |
Apply optimization (ONLY when user explicitly requests) |
Edit/Write |
destructive |
| 5 |
Run tests, lint, type-check, and a benchmark when warranted; report before/after complexity |
Bash test commands |
read-only |
Core Rule
Optimize only when current behavior is understood and can be preserved. Prefer a small, proven improvement with tests over a broad rewrite with unclear correctness.
Default Behavior
When the user asks to analyze, scan, audit, review, or "give me a report" for a codebase, produce the full complexity report automatically. Do not require the user to specify report fields.
Default report contents (see references/report-template.md):
- Scope analyzed and detected stack/test commands
- Top findings ranked by likely impact
- File and line for each finding
- Current pattern and why it may be costly
- Estimated current complexity
- Recommended change and estimated complexity after
- Risk level
- Tests, benchmarks, or manual checks needed
- Clear statement that no files were modified, unless the user explicitly requested implementation
Only edit files when the user uses an explicit edit verb: implement, fix, optimize, apply, change, refactor. If the request is analysis-only or a report-only request, do not modify files.
Workflow Detail
1. Baseline
- Identify language, framework, test command, build command, and performance-sensitive paths.
- Inspect existing tests before touching code.
- Run
python3 scripts/analyze_complexity.py <repo> for a first-pass hotspot list when scanning a repository.
2. Rank
- Prioritize hot paths, large-input paths, rendering loops, database/API loops, shared utilities.
- Separate algorithmic complexity from constant-factor cleanup.
- Treat scanner output as leads, not proof.
- For report-only requests, inspect enough surrounding code to estimate current and proposed complexity. Do not stop at raw scanner output.
3. Prove behavior
- Locate or add focused tests for the function/component being changed.
- Capture edge cases: empty input, duplicates, ordering stability, null/missing values, errors, permissions, pagination, time zones, mutation side effects.
- If tests are absent and behavior is ambiguous, make the smallest possible refactor or ask for expected behavior before changing semantics.
4. Optimize (only on explicit request)
- Replace repeated linear lookup with maps/sets when key equality is stable.
- Replace nested scans with indexing, grouping, two-pointer scans, sweep-line logic, binary search, memoization, batching, or precomputation — only when the data shape supports it.
- In UI code, reduce unnecessary renders with stable props, memoized derived data, virtualization, debounced work, and moving expensive work out of render paths.
- In data access code, remove N+1 with bulk fetches, joins, preloading, caching, or batching while preserving authorization and filtering.
5. Verify
- Run relevant tests and type/lint/build commands.
- Add a micro-benchmark or measurement when the complexity improvement is non-obvious or performance-critical.
- Report original complexity, new complexity, files changed, tests run, and any residual risk.
First-Pass Scanner
python3 scripts/analyze_complexity.py /path/to/repo --format markdown
python3 scripts/analyze_complexity.py /path/to/repo --format json
python3 scripts/analyze_complexity.py /path/to/repo --changed-only --base origin/main
--changed-only restricts the scan to files changed vs --base (default HEAD~1). Use it for PR-focused complexity review.
Language depth:
- Python (
.py) — AST-based analysis. High precision: nested loops, sort/membership in loops, query/I/O in loops, all tracked per-function via the Python ast module.
- All other supported languages (
.js, .ts, .jsx, .tsx, .java, .go, .rb, .php, .cs, .c, .cpp, .swift, .vue, .svelte, .kt, .rs, .dart, .scala) — regex-based pattern matching with indent + function-boundary heuristics. Treat findings as leads; verify by reading the surrounding code before recommending fixes.
If the scanner reports nothing, still inspect known hot paths manually. Rendering churn, database query patterns, and framework lifecycle issues often need repository-specific context the scanner cannot see.
Exit codes: 0 = scanned successfully, 2 = bad input (non-existent path / file instead of directory / git error), 3 = zero files matched, 130 = interrupted.
Triage before reporting: consult references/false-positives.md to dismiss known noise patterns (single-call predicates, Redux selectors, SQL-builder fluent methods, render-derived work on small static arrays) before recommending fixes.
Testing the scanner: python3 scripts/test_analyze_complexity.py runs 13 regression tests that pin the false-positive fixes. Run after modifying the scanner.
Optimization Safety Checklist
Before editing:
- Confirm the data sizes are large enough for complexity to matter.
- Confirm the optimization preserves output ordering where callers may rely on it.
- Confirm object identity, mutability, and reference sharing are not part of public behavior.
- Confirm caches have a valid invalidation strategy.
- Confirm deduplication does not collapse distinct records that share a display label.
- Confirm database batching preserves tenant, permission, soft-delete, pagination, and sorting constraints.
After editing:
- Run the narrowest relevant test first, then the broader build/lint/typecheck.
- Compare before/after benchmark numbers when a benchmark exists or was added.
- Keep the patch localized — avoid formatting churn in unrelated files.
Rollback
If the optimization breaks a test or changes observable behavior:
Revert the changed file(s) immediately:
git restore <file> # restore a single file
git restore -SW <file> # restore both index and working tree
If multiple files were modified: git restore -SW . (only within the affected directory).
Re-run the failing test to confirm restoration.
Report the failure to the user with:
- The exact test/assertion that failed
- The semantics that diverged (ordering, mutation, key equality, etc.)
- Whether to retry with a different transformation, or stay with the original code
Do not re-attempt the same optimization with a small tweak. If a transformation breaks behavior, either the data shape doesn't support it, or there's an unstated invariant — re-read the code before trying again.
References
references/optimization-playbook.md — common O(n^2) → O(n log n) / O(n) transformations, framework-specific patterns, and "What Not To Do".
references/report-template.md — structure for the final analysis or audit output.
references/false-positives.md — catalog of scanner findings that look real but aren't. Consult before recommending fixes.
scripts/_sections.md — scanner invocation, flags, exit codes, and limitations.
1---2name: complexity-optimizer3description: Analyze a software codebase for algorithmic complexity and performance hotspots, then propose or implement safe optimizations without breaking behavior. Use when the user asks to scan many files, find inefficient loops, nested iteration, repeated scans, costly rendering/recomputation, N+1 queries, avoidable O(n^2) or O(n) operations, or reduce complexity such as O(n^2) to O(n log n) / O(n), while preserving tests, APIs, outputs, and maintainability.4---5
6# Complexity Optimizer
7
8Find algorithmic complexity hotspots in a codebase and produce a structured report. Optionally implement low-risk optimizations after explicit consent.
9
10## When to Apply
11
12Use this skill when the user asks to:
13- Analyze, audit, scan, or review a codebase for performance hotspots or algorithmic complexity
14- Find inefficient loops, nested iteration, N+1 queries, sort-in-loop, render-path recomputation
15- Reduce complexity (e.g. O(n^2) → O(n log n) or O(n))
16- "Give me a report" on a codebase's complexity profile
17
18Do not use this skill for:
19- Micro-optimizations on cold code paths
20- Memory tuning (this skill targets time complexity, not allocation profiles)
21- Code style refactoring unrelated to complexity
22
23## Workflow Overview
24
25```
26Baseline → Rank → Prove behavior → Optimize (opt-in) → Verify
27 ↓ ↓ ↓
28 scanner prioritize hot rollback if
29 + manual paths & large I/O tests regress
30```
31
32| Step | Action | Tool | Risk |
33|------|--------|------|------|
34| 1 | Establish baseline: detect stack, test command, hot paths | `scripts/analyze_complexity.py` + manual inspection | read-only |
35| 2 | Rank opportunities by impact, separating algorithmic wins from constant-factor cleanup | reasoning | read-only |
36| 3 | Locate or add tests covering the function/component | Read + test framework | read-only |
37| 4 | Apply optimization (ONLY when user explicitly requests) | Edit/Write | destructive |
38| 5 | Run tests, lint, type-check, and a benchmark when warranted; report before/after complexity | Bash test commands | read-only |
39
40## Core Rule
41
42Optimize only when current behavior is understood and can be preserved. Prefer a small, proven improvement with tests over a broad rewrite with unclear correctness.
43
44## Default Behavior
45
46When the user asks to analyze, scan, audit, review, or "give me a report" for a codebase, produce the full complexity report automatically. Do not require the user to specify report fields.
47
48Default report contents (see `references/report-template.md`):
49
50- Scope analyzed and detected stack/test commands
51- Top findings ranked by likely impact
52- File and line for each finding
53- Current pattern and why it may be costly
54- Estimated current complexity
55- Recommended change and estimated complexity after
56- Risk level
57- Tests, benchmarks, or manual checks needed
58- Clear statement that **no files were modified**, unless the user explicitly requested implementation
59
60Only edit files when the user uses an explicit edit verb: **implement, fix, optimize, apply, change, refactor**. If the request is analysis-only or a report-only request, do not modify files.
61
62## Workflow Detail
63
64### 1. Baseline
65
66- Identify language, framework, test command, build command, and performance-sensitive paths.
67- Inspect existing tests before touching code.
68- Run `python3 scripts/analyze_complexity.py <repo>` for a first-pass hotspot list when scanning a repository.
69
70### 2. Rank
71
72- Prioritize hot paths, large-input paths, rendering loops, database/API loops, shared utilities.
73- Separate algorithmic complexity from constant-factor cleanup.
74- Treat scanner output as leads, not proof.
75- For report-only requests, inspect enough surrounding code to estimate current and proposed complexity. Do not stop at raw scanner output.
76
77### 3. Prove behavior
78
79- Locate or add focused tests for the function/component being changed.
80- Capture edge cases: empty input, duplicates, ordering stability, null/missing values, errors, permissions, pagination, time zones, mutation side effects.
81- If tests are absent and behavior is ambiguous, make the smallest possible refactor or ask for expected behavior before changing semantics.
82
83### 4. Optimize (only on explicit request)
84
85- Replace repeated linear lookup with maps/sets when key equality is stable.
86- Replace nested scans with indexing, grouping, two-pointer scans, sweep-line logic, binary search, memoization, batching, or precomputation — only when the data shape supports it.
87- In UI code, reduce unnecessary renders with stable props, memoized derived data, virtualization, debounced work, and moving expensive work out of render paths.
88- In data access code, remove N+1 with bulk fetches, joins, preloading, caching, or batching while preserving authorization and filtering.
89
90### 5. Verify
91
92- Run relevant tests and type/lint/build commands.
93- Add a micro-benchmark or measurement when the complexity improvement is non-obvious or performance-critical.
94- Report original complexity, new complexity, files changed, tests run, and any residual risk.
95
96## First-Pass Scanner
97
98```bash
99python3 scripts/analyze_complexity.py /path/to/repo --format markdown
100python3 scripts/analyze_complexity.py /path/to/repo --format json
101python3 scripts/analyze_complexity.py /path/to/repo --changed-only --base origin/main
102```
103
104`--changed-only` restricts the scan to files changed vs `--base` (default `HEAD~1`). Use it for PR-focused complexity review.
105
106**Language depth:**
107
108- **Python** (`.py`) — AST-based analysis. High precision: nested loops, sort/membership in loops, query/I/O in loops, all tracked per-function via the Python `ast` module.
109- **All other supported languages** (`.js`, `.ts`, `.jsx`, `.tsx`, `.java`, `.go`, `.rb`, `.php`, `.cs`, `.c`, `.cpp`, `.swift`, `.vue`, `.svelte`, `.kt`, `.rs`, `.dart`, `.scala`) — regex-based pattern matching with indent + function-boundary heuristics. Treat findings as leads; verify by reading the surrounding code before recommending fixes.
110
111If the scanner reports nothing, still inspect known hot paths manually. Rendering churn, database query patterns, and framework lifecycle issues often need repository-specific context the scanner cannot see.
112
113**Exit codes:** `0` = scanned successfully, `2` = bad input (non-existent path / file instead of directory / git error), `3` = zero files matched, `130` = interrupted.
114
115**Triage before reporting:** consult `references/false-positives.md` to dismiss known noise patterns (single-call predicates, Redux selectors, SQL-builder fluent methods, render-derived work on small static arrays) before recommending fixes.
116
117**Testing the scanner:** `python3 scripts/test_analyze_complexity.py` runs 13 regression tests that pin the false-positive fixes. Run after modifying the scanner.
118
119## Optimization Safety Checklist
120
121Before editing:
122
123- Confirm the data sizes are large enough for complexity to matter.
124- Confirm the optimization preserves output ordering where callers may rely on it.
125- Confirm object identity, mutability, and reference sharing are not part of public behavior.
126- Confirm caches have a valid invalidation strategy.
127- Confirm deduplication does not collapse distinct records that share a display label.
128- Confirm database batching preserves tenant, permission, soft-delete, pagination, and sorting constraints.
129
130After editing:
131
132- Run the narrowest relevant test first, then the broader build/lint/typecheck.
133- Compare before/after benchmark numbers when a benchmark exists or was added.
134- Keep the patch localized — avoid formatting churn in unrelated files.
135
136## Rollback
137
138If the optimization breaks a test or changes observable behavior:
139
1401. **Revert the changed file(s) immediately:**
141 ```bash
142 git restore <file> # restore a single file
143 git restore -SW <file> # restore both index and working tree
144 ```
145 If multiple files were modified: `git restore -SW .` (only within the affected directory).
146
1472. **Re-run the failing test** to confirm restoration.
148
1493. **Report the failure to the user** with:
150 - The exact test/assertion that failed
151 - The semantics that diverged (ordering, mutation, key equality, etc.)
152 - Whether to retry with a different transformation, or stay with the original code
153
1544. **Do not** re-attempt the same optimization with a small tweak. If a transformation breaks behavior, either the data shape doesn't support it, or there's an unstated invariant — re-read the code before trying again.
155
156## References
157
158- `references/optimization-playbook.md` — common O(n^2) → O(n log n) / O(n) transformations, framework-specific patterns, and "What Not To Do".
159- `references/report-template.md` — structure for the final analysis or audit output.
160- `references/false-positives.md` — catalog of scanner findings that look real but aren't. Consult before recommending fixes.
161- `scripts/_sections.md` — scanner invocation, flags, exit codes, and limitations.