Optimizes algorithm complexity and code efficiency to improve execution speed through better data structures, algorithms, and implementation patterns.
Optimizes algorithm complexity and code efficiency to improve execution speed through better data structures, algorithms, and implementation patterns.
/plugin marketplace add avovello/cc-plugins/plugin install optimize@cc-pluginsOptimizes algorithm complexity and code efficiency to improve execution speed through better data structures, algorithms, and implementation patterns.
✅ DOES:
❌ DOES NOT:
O(n²) → O(n log n): Use efficient sorting
// ❌ Bubble sort O(n²)
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
return arr;
}
// ✅ Use built-in sort O(n log n)
function efficientSort(arr) {
return [...arr].sort((a, b) => a - b);
}
// Benchmark: 10,000 items
// Before: 850ms
// After: 12ms (71× faster)
O(n²) → O(n): Use hash map for lookups
// ❌ Nested loop O(n²)
function findCommon(arr1, arr2) {
const common = [];
for (let item1 of arr1) {
for (let item2 of arr2) {
if (item1 === item2) {
common.push(item1);
}
}
}
return common;
}
// ✅ Hash map O(n)
function findCommonOptimized(arr1, arr2) {
const set1 = new Set(arr1);
return arr2.filter(item => set1.has(item));
}
// Benchmark: 1,000 items each
// Before: 125ms (1,000,000 comparisons)
// After: 2ms (2,000 operations, 62× faster)
Array → Hash Map for frequent lookups
# ❌ Array lookup O(n)
def get_user_by_id(users_array, user_id):
for user in users_array: # O(n)
if user['id'] == user_id:
return user
return None
# ✅ Dictionary lookup O(1)
def create_user_map(users_array):
return {user['id']: user for user in users_array}
user_map = create_user_map(users)
user = user_map.get(user_id) # O(1)
# Benchmark: 10,000 users, 1,000 lookups
# Before: 5,200ms (10M comparisons)
# After: 1ms (1,000 hash lookups, 5,200× faster)
List → Set for membership testing
# ❌ List membership O(n)
allowed_users = [1, 5, 12, 45, 67, ...] # 1000 items
if user_id in allowed_users: # O(n) - scans entire list
grant_access()
# ✅ Set membership O(1)
allowed_users = {1, 5, 12, 45, 67, ...}
if user_id in allowed_users: # O(1) - hash lookup
grant_access()
# Benchmark: 1,000 items, 10,000 checks
# Before: 250ms
# After: 2ms (125× faster)
Move calculations outside loops
// ❌ Redundant calculation inside loop
function processItems(items, multiplier) {
const results = [];
for (let i = 0; i < items.length; i++) {
const factor = multiplier * 1.1; // Calculated every iteration!
results.push(items[i] * factor);
}
return results;
}
// ✅ Calculate once
function processItemsOptimized(items, multiplier) {
const factor = multiplier * 1.1; // Calculated once
return items.map(item => item * factor);
}
// Benchmark: 100,000 items
// Before: 45ms
// After: 12ms (73% faster)
Cache expensive computations
# ❌ Recalculating Fibonacci
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2) # Exponential time!
# fibonacci(40) = 102,334,155 calls, 3+ seconds
# ✅ Memoization
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci_fast(n):
if n <= 1:
return n
return fibonacci_fast(n-1) + fibonacci_fast(n-2)
# fibonacci_fast(40) = 79 calls, <1ms (3,000,000× faster)
Avoid repeated string concatenation
# ❌ String concatenation in loop O(n²)
def build_csv(rows):
result = ""
for row in rows:
result += ",".join(row) + "\n" # Creates new string each time!
return result
# 10,000 rows = 10,000 string allocations
# ✅ Use list join O(n)
def build_csv_optimized(rows):
lines = [",".join(row) for row in rows]
return "\n".join(lines) # One allocation
# Benchmark: 10,000 rows
# Before: 850ms
# After: 25ms (34× faster)
Use string builder for large strings
// ❌ String concatenation
String result = "";
for (int i = 0; i < 10000; i++) {
result += "Item " + i + "\n"; // Creates 10,000 new strings!
}
// ✅ StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append("Item ").append(i).append("\n");
}
String result = sb.toString();
// Benchmark: 10,000 items
// Before: 2,400ms
// After: 8ms (300× faster)
Early termination
// ❌ Checks all items even after finding match
function hasLargeValue(items) {
let found = false;
for (let item of items) {
if (item > 1000) {
found = true;
}
}
return found;
}
// ✅ Return immediately
function hasLargeValueOptimized(items) {
for (let item of items) {
if (item > 1000) {
return true; // Early exit!
}
}
return false;
}
// Benchmark: 100,000 items, match at position 10
// Before: 45ms (checks all 100,000)
// After: <1ms (checks 10, 4,500× faster)
Reverse loops for array mutation
// ❌ Forward loop with splice (shifts elements)
function removeEvenNumbers(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
arr.splice(i, 1); // O(n) operation, done n times = O(n²)
i--; // Adjust index
}
}
}
// ✅ Reverse loop or filter
function removeEvenNumbersOptimized(arr) {
// Option 1: Reverse loop
for (let i = arr.length - 1; i >= 0; i--) {
if (arr[i] % 2 === 0) {
arr.splice(i, 1); // No shifting of remaining elements
}
}
// Option 2: Filter (immutable, often faster)
return arr.filter(n => n % 2 !== 0);
}
// Benchmark: 10,000 items
// Before: 450ms
// After: 12ms (38× faster)
Reuse objects instead of creating new ones
// ❌ Creates new objects in loop
function processPoints(points) {
const results = [];
for (let point of points) {
results.push({ // New object allocation
x: point.x * 2,
y: point.y * 2
});
}
return results;
}
// ✅ Mutate existing objects (if safe)
function processPointsOptimized(points) {
for (let point of points) {
point.x *= 2;
point.y *= 2;
}
return points;
}
// Or use object pool for immutability
class PointPool {
constructor() {
this.pool = [];
}
get() {
return this.pool.pop() || { x: 0, y: 0 };
}
release(point) {
this.pool.push(point);
}
}
// Benchmark: 100,000 points
// Before: 125ms + 10MB allocations
// After: 15ms + minimal allocations (8× faster)
# Profile to find slow functions
node --prof app.js
node --prof-process isolate-*.log > profile.txt
# Python
python -m cProfile -o profile.stats app.py
python -m pstats profile.stats
// Benchmark helper
function benchmark(fn, iterations = 1000) {
const start = performance.now();
for (let i = 0; i < iterations; i++) {
fn();
}
const end = performance.now();
return {
total: end - start,
average: (end - start) / iterations
};
}
// Test
const data = generateTestData(10000);
const baseline = benchmark(() => processData(data));
console.log(`Baseline: ${baseline.average}ms per iteration`);
// Before: O(n²) nested loop
function findDuplicates(arr) {
const duplicates = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j] && !duplicates.includes(arr[i])) {
duplicates.push(arr[i]);
}
}
}
return duplicates;
}
// After: O(n) hash map
function findDuplicatesOptimized(arr) {
const seen = new Map();
const duplicates = new Set();
for (let item of arr) {
if (seen.has(item)) {
duplicates.add(item);
} else {
seen.set(item, true);
}
}
return Array.from(duplicates);
}
const optimized = benchmark(() => findDuplicatesOptimized(data));
console.log(`Before: ${baseline.average}ms`);
console.log(`After: ${optimized.average}ms`);
console.log(`Improvement: ${((baseline.average - optimized.average) / baseline.average * 100).toFixed(1)}% faster`);
// Output:
// Before: 850ms
// After: 12ms
// Improvement: 98.6% faster
// Ensure same results
const testCases = [
[1, 2, 3, 2, 4, 3, 5],
[1, 1, 1, 1],
[1, 2, 3, 4, 5],
[]
];
for (let testCase of testCases) {
const original = findDuplicates(testCase);
const optimized = findDuplicatesOptimized(testCase);
assert.deepEqual(
original.sort(),
optimized.sort(),
'Results must match'
);
}
console.log('✅ All tests pass - optimization preserves behavior');
# Code Optimization Report
**Date**: 2025-01-15
**Target**: findDuplicates function
**File**: src/utils/array-helpers.js:45
## Summary
- **Complexity**: O(n²) → O(n) (quadratic to linear)
- **Performance**: 850ms → 12ms (98.6% faster, 71× speedup)
- **Algorithm**: Nested loops → Hash map
- **Tests**: ✅ All 24 tests pass
## Optimization Details
### Before
**Code**:
```javascript
function findDuplicates(arr) {
const duplicates = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j] && !duplicates.includes(arr[i])) {
duplicates.push(arr[i]);
}
}
}
return duplicates;
}
Complexity Analysis:
includes() check: O(n)Performance:
Code:
function findDuplicatesOptimized(arr) {
const seen = new Map();
const duplicates = new Set();
for (let item of arr) {
if (seen.has(item)) {
duplicates.add(item);
} else {
seen.set(item, true);
}
}
return Array.from(duplicates);
}
Complexity Analysis:
Performance:
| Input Size | Before | After | Speedup |
|---|---|---|---|
| 10 | <1ms | <1ms | 1× |
| 100 | 45ms | 1ms | 45× |
| 1,000 | 850ms | 2ms | 425× |
| 10,000 | ~85s | 12ms | ~7,000× |
Scalability: Linear vs quadratic growth
✅ Test case 1: [1, 2, 3, 2, 4, 3, 5]
Expected: [2, 3]
Got: [2, 3] ✓
✅ Test case 2: [1, 1, 1, 1]
Expected: [1]
Got: [1] ✓
✅ Test case 3: [1, 2, 3, 4, 5]
Expected: []
Got: [] ✓
✅ All 24 tests pass
In Production:
User Experience:
Use this agent when analyzing conversation transcripts to find behaviors worth preventing with hooks. Examples: <example>Context: User is running /hookify command without arguments user: "/hookify" assistant: "I'll analyze the conversation to find behaviors you want to prevent" <commentary>The /hookify command without arguments triggers conversation analysis to find unwanted behaviors.</commentary></example><example>Context: User wants to create hooks from recent frustrations user: "Can you look back at this conversation and help me create hooks for the mistakes you made?" assistant: "I'll use the conversation-analyzer agent to identify the issues and suggest hooks." <commentary>User explicitly asks to analyze conversation for mistakes that should be prevented.</commentary></example>