Optimize Code Complexity
Lowers Big-O on existing, working code via one transformation at a time, tests green before and after, and a measured speedup ratio.
Why it matters
Reduce the time and space complexity of existing codebases to improve performance and resource utilization. This skill focuses on refactoring code with poor Big-O notation, ensuring semantic correctness and verifiable improvements.
Outcomes
What it gets done
Identify and fix nested loops and redundant computations.
Optimize N+1 query patterns in ORMs.
Refactor serial latency issues caused by awaits in loops.
Improve memory usage by avoiding unnecessary allocations and data structures.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/ag-complexity-cuts | bash Overview
complexity-cuts - Lower Big-O on Existing Code
Refactors existing, already-working code to lower its time or space complexity - nested loops, O(n^2)+ scans, redundant allocations, N+1 ORM queries - using a strict test-verified, one-transformation-at-a-time process with a documented playbook of smell-to-fix mappings, and requires reporting a measured before/after speedup ratio rather than invented numbers. Use it when refactoring code that's slow on large inputs, times out, or runs out of memory. Use lemmaly instead to prevent bad complexity before code is written, and mathguard for math-level optimizations like Bloom filters or FFT.
What it does
complexity-cuts refactors existing, already-working code whose time or space complexity is worse than necessary - nested loops, O(n^2)+ scans, repeated work, redundant allocations, blown memory, N+1 ORM query patterns, or serial await inside a for over independent items. Its Iron Law: no transformation without existing tests green before and after - if no tests exist, it writes a characterization test (golden input to current output) first, since a faster-but-wrong rewrite is worse than slow-and-right.
When to use - and when NOT to
Use it when refactoring code that's slow on large inputs, times out, runs out of memory, or is explicitly flagged for complexity reduction - including N+1 patterns in Prisma/Drizzle/SQLAlchemy/Django/ActiveRecord. It's a sibling to two other skills: lemmaly prevents bad complexity before code is written (this skill only fixes it after the fact), and mathguard handles math-level optimizations (Bloom filters, HyperLogLog, FFT, Johnson-Lindenstrauss projection) beyond this skill's scope.
Inputs and outputs
Before touching code, it states current and target Big-O in one line (time, space, and the dominant input dimension) and identifies the exact bottleneck line(s) rather than guessing. Then it applies exactly one transformation from a documented playbook at a time, in a strict verify-revert-stop loop: apply, run tests, revert immediately on any failure (never patch the test or the failure), and stop optimizing entirely after 3 reverts in a row on the same code - escalating to invariant-guard rather than trying a fourth transformation. The playbook catalogs specific smell-to-fix mappings with expected wins: for x in A: if x in B on a list becomes a Set/Map lookup (O(n·m) to O(n+m)); nested loops computing joins become hash-joins; repeated .find/.indexOf inside a loop becomes a precomputed index map (O(n^2) to O(n)); naive recursive Fibonacci-shaped recomputation becomes memoization or iterative DP (exponential to O(n)); await inside a loop over independent items becomes Promise.all/batched concurrency; N+1 ORM queries become IN (...)/select_related/bulk fetch. Space-side fixes include swapping full-list materialization for generators/streams, single-pass pipelines instead of chained .map().filter().map(), bounded LRU caches instead of unbounded ones, and cursor/pagination instead of loading a full DB result set. Semantics must be preserved exactly - if a transformation would change output ordering or behavior, that must be called out explicitly and confirmed acceptable, and no speedup number may be invented; every landed transformation must report an actual measured before/after ratio (e.g. "p50: 186ms -> 1.1ms, 169x faster, n=20,000"), or explicitly state "asymptotic only, no measurement" if measurement isn't possible.
Integrations
When asymptotic complexity truly can't go lower (e.g. O(n log n) is the real floor), the skill falls back to constant-factor wins: contiguous arrays over pointer-chasing structures for cache locality, and similar low-level optimizations, rather than forcing a semantically risky asymptotic change.
Who it's for
Developers optimizing already-correct code that's too slow or memory-hungry on real inputs, who need a disciplined, test-verified, one-change-at-a-time process instead of a risky big-bang rewrite that might silently break callers.
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.