Skip to content
NeuralSkills
Code Review

Performance Code Review

Review code for performance issues: O(n squared) loops, memory leaks, unnecessary renders, and slow queries.

Intermediate Free Published: April 15, 2026
Compatible Tools claude-codechatgptgeminicopilotcursorwindsurfuniversal

The Problem

Performance bugs rarely trigger errors — they just make everything slower. A nested loop that works fine with 100 items crawls at 10,000. A React component re-renders 47 times per keystroke because a callback is recreated every render. A database query fetches 50 related records one at a time instead of in a single join. These issues ship unnoticed until users complain or servers buckle under load.

The Prompt

Review the following code for performance issues. Act as a performance engineer profiling a production system under high load.

LANGUAGE/FRAMEWORK: [e.g., TypeScript/React, Python/Django, Rust]
EXPECTED SCALE: [e.g., 10k concurrent users, 1M database rows, mobile devices]

CODE:
[paste your code here]

Analyze across these performance dimensions:

1. **Algorithmic Complexity**
   - Identify any O(n^2) or worse operations (nested loops, repeated array scans)
   - Flag operations that should use a Set/Map for O(1) lookups instead of array.find/includes
   - Check for redundant computation that could be cached/memoized

2. **Memory**
   - Large object allocations inside loops or hot paths
   - Missing cleanup (event listeners, intervals, subscriptions)
   - Unbounded arrays/caches that grow without limits

3. **Rendering (Frontend)**
   - Components re-rendering without prop changes
   - Missing useMemo/useCallback for expensive computations or callback props
   - Layout thrashing (reading DOM → writing DOM → reading DOM)

4. **I/O and Network**
   - N+1 query patterns (fetching related data in loops)
   - Missing pagination on list endpoints
   - Sequential awaits that could be Promise.all
   - Missing request deduplication or caching

5. **Bundle and Loading**
   - Large imports that could be lazy-loaded
   - Synchronous operations blocking the main thread
   - Missing code splitting opportunities

For each issue, provide:
- **Location**: File and line
- **Impact**: Quantified estimate (e.g., "47 re-renders per keystroke", "O(n^2) with n=users")
- **Severity**: critical / moderate / minor
- **Fix**: Optimized code replacement
- **Tradeoff**: Any readability or complexity cost of the optimization

Example Output

## Performance Review: 5 issues found

### Critical: N+1 Query Pattern
Location: src/api/orders.ts:23
Impact: 1 query per order item. With 200 orders × 5 items = 1,000 queries instead of 2.
Code:
  for (const order of orders) {
    order.items = await db.query("SELECT * FROM items WHERE order_id = ?", [order.id]);
  }
Fix:
  const orderIds = orders.map(o => o.id);
  const items = await db.query("SELECT * FROM items WHERE order_id IN (?)", [orderIds]);
  // Group by order_id in application code
Tradeoff: Slightly more memory to hold all items at once. Negligible at this scale.

### Moderate: Unnecessary Re-renders
Location: src/components/SearchResults.tsx:15
Impact: Every keystroke re-renders all 50 result cards because filter function is recreated.
Fix: Wrap with useMemo:
  const filtered = useMemo(() => results.filter(r => r.name.includes(query)), [results, query]);

When to Use

Run this before deploying features that handle lists, user-generated content, or database queries at scale. Especially valuable when moving from prototype (100 records) to production (100,000 records) — the performance patterns that work at small scale often collapse at real scale.

Pro Tips

  • Specify your scale — “1,000 users” and “1,000,000 users” demand completely different optimization strategies. Always include expected data volume.
  • Ask for Big-O annotations — request “Annotate each function with its time and space complexity” to get a complexity map of your code.
  • Profile first, optimize second — use this review to identify suspects, then confirm with real profiling data before rewriting.