Skip to content

Appendix A: Complexity Cheat Sheet

A comprehensive reference for algorithm complexity analysis and common algorithm time/space complexities.

From fastest to slowest:

NotationNameExamplen=10n=100n=1000
O(1)ConstantArray access, hash lookup111
O(log n)LogarithmicBinary search3710
O(n)LinearLinear search, array iteration101001,000
O(n log n)LinearithmicMerge sort, quick sort (avg)306649,966
O(n²)QuadraticBubble sort, nested loops10010,0001,000,000
O(n³)CubicMatrix multiplication1,0001,000,0001,000,000,000
O(2ⁿ)ExponentialRecursive Fibonacci1,0241.27×10³⁰
O(n!)FactorialTraveling salesman (brute force)3,628,800
ComplexityMaximum n
O(1)
O(log n)
O(n)~100,000,000
O(n log n)~10,000,000
O(n²)~10,000
O(n³)~500
O(2ⁿ)~25
O(n!)~11
Operations performed (y-axis) vs Input Size (x-axis)
n=10 n=100 n=1000 n=10000
│ │ │ │
│ │ │ │ O(n!)
│ │ │ │xxxxxxxxx
│ │ │ xxxxxxxxxxxx│
│ │ xxxxxxxxxxxx│ │
│ xxxxxxxxxxxx│ │ │ O(2^n)
│ │ │ │xxxxxxx
│ │ │ xxxxxxxxxxx│
│ │ xxxxxxxxxxx│ │
│ xxxxxxxxxxx│ │ │ O(n³)
│ │ │ │xxxxx
│ │ │ xxxxxxxxx │
│ │ xxxxxxxxx │ │
│ xxxxxxxxx │ │ │ O(n²)
│ │ │ xxxx │
│ │ xxx │ │
│ xx │ │ │ O(n log n)
│ │ xx │ xx │
│ x │ │ │ O(n)
│ x │ x │ x │
│ x │ │ x O(log n)
│xxxxxxxxxx ─┼─────────x ─┼────────────x┼─ O(1)
└────────────┴─────────────┴─────────────┴─────────
Legend: Lower = Better Performance
Algorithm Operations Visualization
O(1) 1 █
O(log n) 7 ███
O(n) 100 ██████████
O(n log n) 664 ████████████████████████████████████
O(n²) 10,000 ████████████████████████████████████████████████████... (entire screen!)
O(2^n) 1.27×10³⁰ (larger than atoms in universe)

Key Insight: Even small differences in complexity class have MASSIVE impacts as input grows!

O(1) - Constant Time:

constant-time-example.php
<?php
declare(strict_types=1);
// Direct array access
$value = $array[$key]; // Always same time
// Hash table operations
isset($cache[$key]); // Instant lookup
unset($map[$key]); // Instant delete

See: Chapter 4 (Arrays), Chapter 6 (Hash Tables)

O(log n) - Logarithmic:

logarithmic-example.php
<?php
declare(strict_types=1);
// Binary search on sorted array
$index = binarySearch($sortedArray, $target);
// Operations on balanced BST
$tree->search($value); // Height = log n

See: Chapter 8 (Binary Search), Chapter 16 (Binary Search Trees)

O(n) - Linear:

linear-example.php
<?php
declare(strict_types=1);
// Single loop through array
foreach ($array as $item) {
process($item);
}
// Linear search
$found = in_array($needle, $haystack);

See: Chapter 4 (Array Traversal), Chapter 7 (Linear Search)

O(n log n) - Linearithmic:

linearithmic-example.php
<?php
declare(strict_types=1);
// Efficient sorting
sort($array); // PHP's built-in
$merged = mergeSort($array); // Merge sort

See: Chapter 10-11 (Sorting Algorithms)

O(n²) - Quadratic:

quadratic-example.php
<?php
declare(strict_types=1);
// Nested loops
$count = count($arr);
for ($i = 0; $i < $count; $i++) {
for ($j = $i + 1; $j < $count; $j++) {
comparePair($arr[$i], $arr[$j]);
}
}

See: Chapter 9 (Bubble Sort), Chapter 11 (Selection Sort)

O(2^n) - Exponential:

exponential-example.php
<?php
declare(strict_types=1);
// Naive recursive Fibonacci
function fib(int $n): int {
if ($n <= 1) return $n;
return fib($n-1) + fib($n-2); // Two recursive calls
}

See: Chapter 25 (Dynamic Programming - shows optimization)

O(n!) - Factorial:

factorial-example.php
<?php
declare(strict_types=1);
// Generate all permutations
function permutations(array $items): array {
if (count($items) <= 1) return [$items];
$result = [];
foreach ($items as $i => $item) {
$rest = $items;
unset($rest[$i]);
foreach (permutations(array_values($rest)) as $perm) {
$result[] = array_merge([$item], $perm);
}
}
return $result;
}

See: Chapter 25 (Dynamic Programming - shows optimization)

OperationAverageWorstNotes
Access by indexO(1)O(1)Direct access
Search (unsorted)O(n)O(n)Linear scan
Search (sorted)O(log n)O(log n)Binary search
Insert at endO(1)O(1)$arr[] = $value
Insert at beginningO(n)O(n)array_unshift()
Insert at middleO(n)O(n)Shift elements
Delete at endO(1)O(1)array_pop()
Delete at beginningO(n)O(n)array_shift()
Delete at middleO(n)O(n)Shift elements
OperationAverageWorstNotes
AccessO(1)O(n)Key lookup
SearchO(1)O(n)isset(), array_key_exists()
InsertO(1)O(n)$arr[$key] = $value
DeleteO(1)O(n)unset($arr[$key])
IterationO(n)O(n)foreach
OperationTimeNotes
PushO(1)$stack->push() or array_push()
PopO(1)$stack->pop() or array_pop()
PeekO(1)$stack->top() or end()
SearchO(n)Linear scan
OperationTimeNotes
EnqueueO(1)$queue->enqueue()
DequeueO(1)$queue->dequeue()
PeekO(1)Front element
SearchO(n)Linear scan
OperationAverageWorst (unbalanced)
SearchO(log n)O(n)
InsertO(log n)O(n)
DeleteO(log n)O(n)
Min/MaxO(log n)O(n)
OperationTimeSpaceNotes
SearchO(log n)O(1)Height bounded by 1.44 × log(n)
InsertO(log n)O(1)May require rotations
DeleteO(log n)O(1)May require rotations
Min/MaxO(log n)O(1)Height field per node
SpaceO(n)O(n)Strict balance maintained
OperationTimeSpaceNotes
SearchO(log n)O(1)Height bounded by 2 × log(n)
InsertO(log n)O(1)Max 2 rotations
DeleteO(log n)O(1)Max 3 rotations
Min/MaxO(log n)O(1)Color bit per node
SpaceO(n)O(n)Looser balance than AVL

Comparison:

  • AVL: Stricter balance, faster searches, more rotations on insert/delete
  • Red-Black: Looser balance, faster insertions/deletions, slightly slower searches
  • Both guarantee O(log n) worst-case performance

See: Chapter 20 (Balanced Trees: AVL & Red-Black Trees)

Heap (SplPriorityQueue, SplMinHeap, SplMaxHeap)

Section titled “Heap (SplPriorityQueue, SplMinHeap, SplMaxHeap)”
OperationTime
InsertO(log n)
Extract min/maxO(log n)
Peek min/maxO(1)
Build heapO(n)
HeapifyO(log n)
OperationTimeSpace
Add vertexO(1)O(1)
Add edgeO(1)O(1)
Remove vertexO(V + E)-
Remove edgeO(E)-
Query edgeO(V)-
AlgorithmBestAverageWorstSpaceStableNotes
Bubble SortO(n)O(n²)O(n²)O(1)YesSimple, slow
Selection SortO(n²)O(n²)O(n²)O(1)NoAlways O(n²)
Insertion SortO(n)O(n²)O(n²)O(1)YesGood for small/nearly sorted
Merge SortO(n log n)O(n log n)O(n log n)O(n)YesPredictable, needs space
Quick SortO(n log n)O(n log n)O(n²)O(log n)NoFast average, in-place
Heap SortO(n log n)O(n log n)O(n log n)O(1)NoIn-place, not stable
Counting SortO(n + k)O(n + k)O(n + k)O(k)YesInteger keys only
Radix SortO(nk)O(nk)O(nk)O(n + k)YesInteger keys
Bucket SortO(n + k)O(n + k)O(n²)O(n)YesUniform distribution

PHP’s sort() and usort(): O(n log n) average (uses quicksort variant)

AlgorithmTimeSpaceNotes
Linear SearchO(n)O(1)Unsorted data
Binary SearchO(log n)O(1)Sorted data required
Jump SearchO(√n)O(1)Sorted data
Interpolation SearchO(log log n) avgO(1)Uniformly distributed
Hash Table LookupO(1) avgO(n)PHP arrays
Binary Search TreeO(log n) avgO(n)Balanced tree
Depth-First Search (DFS)O(V + E)O(V)Graph traversal
Breadth-First Search (BFS)O(V + E)O(V)Graph traversal
AlgorithmTime ComplexitySpaceUse Case
DFSO(V + E)O(V)Traversal, cycles
BFSO(V + E)O(V)Shortest path (unweighted)
DijkstraO((V + E) log V)O(V)Shortest path (weighted)
Bellman-FordO(VE)O(V)Negative weights allowed
Floyd-WarshallO(V³)O(V²)All-pairs shortest paths
Prim’sO((V + E) log V)O(V)Minimum spanning tree
Kruskal’sO(E log E)O(V)Minimum spanning tree
Topological SortO(V + E)O(V)DAG ordering
AlgorithmTimeSpaceUse Case
Naive String MatchO(nm)O(1)Simple pattern search
KMPO(n + m)O(m)Pattern matching
Boyer-MooreO(n/m) bestO(m)Fast pattern matching
Rabin-KarpO(n + m) avg, O(nm) worstO(1)Multiple patterns
Aho-CorasickO(n + m + z)O(m × σ)Multi-pattern search
Z-AlgorithmO(n + m)O(n + m)Fast pattern matching
Suffix ArrayO(n log n) build, O(m log n + occ) searchO(n)Substring queries
Suffix TreeO(n) build (Ukkonen’s), O(m) searchO(n)Linear-time pattern matching
Longest Common SubsequenceO(nm)O(nm)Sequence comparison
Edit DistanceO(nm)O(nm)String similarity
Manacher’s AlgorithmO(n)O(n)Palindrome finding

Notes:

  • Aho-Corasick: n = text length, m = total pattern length, z = number of matches, σ = alphabet size
  • Suffix Array: occ = number of occurrences, specialized algorithms can build in O(n)
  • Suffix Tree: Uses Ukkonen’s algorithm for linear construction
ProblemTimeSpace
Fibonacci (naive)O(2ⁿ)O(n)
Fibonacci (DP)O(n)O(n)
Fibonacci (optimized)O(n)O(1)
0/1 KnapsackO(nW)O(nW)
Longest Common SubsequenceO(nm)O(nm)
Longest Increasing SubsequenceO(n²) or O(n log n)O(n)
Matrix Chain MultiplicationO(n³)O(n²)
Edit DistanceO(nm)O(nm)
Coin ChangeO(nA)O(n)

Stream processing algorithms handle continuous, potentially infinite data streams with constant or logarithmic space complexity.

AlgorithmTime per ElementSpaceNotes
Fixed-Size Sliding WindowO(1) add/sum/avg, O(n) min/maxO(n)Window size n
Optimized Sliding WindowO(1) amortized all opsO(n)Uses monotonic queues
Time-Based Sliding WindowO(1) add, O(n) cleanupO(n)n = events in window
Token Bucket Rate LimiterO(1)O(1)Constant space
Leaky Bucket Rate LimiterO(1)O(1)Constant space
Sliding Window CounterO(1)O(k)k = time buckets
Moving Average (SMA)O(1)O(n)n = window size
Exponential Moving Average (EMA)O(1)O(1)Constant space
Top-K ElementsO(1) add, O(n log n) queryO(n)n = unique elements
Reservoir SamplingO(1)O(k)k = sample size
Stream AggregatorO(1) per recordO(n)n = stored values

See: Chapter 36 (Stream Processing Algorithms)

Probabilistic algorithms trade perfect accuracy for dramatic space/time improvements, essential for big data processing.

AlgorithmTimeSpaceAccuracyUse Case
Bloom FilterO(k) add/containsO(m)No false negativesMembership testing
HyperLogLogO(1) addO(2^p)±0.81% (p=14)Cardinality estimation
Count-Min SketchO(d) add/estimateO(w×d)±εNFrequency estimation
Reservoir SamplingO(1) addO(k)Exact distributionRandom sampling
Morris CounterO(1) incrementO(1)±√nApproximate counting
Skip ListO(log n) avgO(n log n)ExactSorted set operations

Notes:

  • Bloom Filter: k = number of hash functions, m = bit array size
  • HyperLogLog: p = precision parameter (typically 14)
  • Count-Min Sketch: w = width, d = depth (hash functions)
  • Reservoir Sampling: k = sample size

See: Chapter 32 (Probabilistic Algorithms)

Concurrent algorithms enable parallel execution, dramatically improving performance for I/O-bound and CPU-intensive tasks.

PatternTime ComplexitySpaceNotes
Async I/O (ReactPHP)O(1) schedulingO(n)n = concurrent operations
Parallel ProcessingO(n/p)O(n)p = processors
Coroutines (Swoole)O(1) yield/resumeO(k)k = coroutine stack
Worker PoolO(n/p)O(p)p = workers, n = tasks
Pipeline ProcessingO(n)O(k)k = pipeline stages
Fork-JoinO(n/p + log p)O(n)Divide and conquer

Notes:

  • Concurrent algorithms reduce wall-clock time but may increase total CPU time
  • Space complexity often increases due to multiple execution contexts
  • Actual speedup depends on I/O wait time and CPU cores available

See: Chapter 31 (Concurrent Algorithms)

FunctionTimeSpaceNotes
in_array()O(n)O(1)Linear search - avoid in loops
array_search()O(n)O(1)Linear search - returns key
isset()O(1)O(1)Hash lookup - use for membership
array_key_exists()O(1)O(1)Hash lookup - checks null values too
count()O(1)O(1)Stored value - cache outside loops
array_push()O(1)O(1)Append - same as $arr[] = $val
array_pop()O(1)O(1)Remove last
array_shift()O(n)O(1)Remove first, reindex - use SplQueue
array_unshift()O(n)O(1)Prepend, reindex - expensive
array_merge()O(n + m)O(n + m)Combine arrays
array_merge_recursive()O(n + m)O(n + m)Deep merge
array_combine()O(n)O(n)Keys + values to array
array_fill()O(n)O(n)Fill with value
array_pad()O(n)O(n)Pad to length
array_chunk()O(n)O(n)Split into chunks
array_column()O(n)O(n)Extract column from 2D array
array_flip()O(n)O(n)Swap keys and values
array_intersect()O(n * m)O(n)Common values
array_diff()O(n * m)O(n)Difference
array_values()O(n)O(n)Reindex numerically
array_keys()O(n)O(n)Extract keys
sort()O(n log n)O(log n)Quicksort variant
rsort()O(n log n)O(log n)Reverse sort
asort()O(n log n)O(log n)Sort maintaining keys
ksort()O(n log n)O(log n)Sort by keys
usort()O(n log n)O(log n)Custom comparison sort
array_unique()O(n)O(n)Hash-based deduplication
array_filter()O(n)O(n)Iterate + callback
array_map()O(n)O(n)Iterate + transform
array_reduce()O(n)O(1)Iterate + accumulate
array_walk()O(n)O(1)In-place modification
array_reverse()O(n)O(n)Reverse order
array_slice()O(k)O(k)Extract k elements
array_splice()O(n)O(k)Remove and replace
array_sum()O(n)O(1)Sum numeric array
array_product()O(n)O(1)Product of array
min() / max()O(n)O(1)Find min/max in array
FunctionTimeSpaceNotes
strlen()O(1)O(1)Cached length
substr()O(k)O(k)Extract k characters
strpos()O(n)O(1)Find substring - fast
str_contains()O(n)O(1)PHP 8.0+ - check substring
str_starts_with()O(m)O(1)PHP 8.0+ - check prefix
str_ends_with()O(m)O(1)PHP 8.0+ - check suffix
str_replace()O(n)O(n)Simple replacement
str_ireplace()O(n)O(n)Case-insensitive replace
preg_match()O(n) avgO(1)Regex - can be O(2^n) worst
preg_replace()O(n) avgO(n)Regex replacement
explode()O(n)O(n)Split string
implode()O(n)O(n)Join strings
trim() / ltrim() / rtrim()O(n)O(n)Remove whitespace
strtoupper() / strtolower()O(n)O(n)Case conversion
strcmp()O(n)O(1)String comparison
levenshtein()O(n * m)O(n * m)Edit distance
FunctionTimeSpaceNotes
str_contains()O(n)O(1)Better than strpos() !== false
str_starts_with()O(m)O(1)Better than substr($str, 0, m)
str_ends_with()O(m)O(1)Better than substring comparison
array_is_list()O(n)O(1)Check if sequential numeric keys
fdiv()O(1)O(1)Division by zero returns INF
Match expressionO(1)O(1)Strict comparison switch
FeatureTimeSpaceNotes
Property hooksO(1)O(1)Overhead per property access
Asymmetric visibilityO(1)O(1)No performance impact
Typed class constantsO(1)O(1)Compile-time check
Override attributeO(1)O(1)Compile-time validation
OperationSplStackSplQueueSplHeapSplFixedArray
AccessO(1) topO(1) frontO(1) topO(1) by index
InsertO(1) pushO(1) enqueueO(log n)O(1) at index
DeleteO(1) popO(1) dequeueO(log n)O(1) at index
SearchO(n)O(n)O(n)O(n)
SpaceO(n)O(n)O(n)O(n) fixed

Example: When to use each:

queue-comparison.php
<?php
declare(strict_types=1);
// ❌ BAD: Using array_shift in loop (O(n²) total)
while (count($arr) > 0) {
$item = array_shift($arr); // O(n) each time
process($item);
}
// ✅ GOOD: Using SplQueue (O(n) total)
$queue = new SplQueue();
foreach ($arr as $item) {
$queue->enqueue($item);
}
while (!$queue->isEmpty()) {
$item = $queue->dequeue(); // O(1) each time
process($item);
}
PatternSpaceExample
In-place algorithmO(1)Bubble sort, two pointers
Single array/variableO(n)Hash table, visited set
Two arraysO(n)Merge sort temp array
MatrixO(n²)Floyd-Warshall, DP table
Recursion depthO(n)DFS call stack
Complete binary treeO(2ⁿ)All subsets generation
Stream processingO(1) or O(log n)Sliding windows, aggregations
Probabilistic structuresO(1) to O(k)Bloom filters, sketches
Concurrent contextsO(p)p = parallel workers/threads
memory-overhead.php
<?php
declare(strict_types=1);
// Array overhead
$arr = []; // ~56 bytes base
$arr[] = 1; // ~72 bytes per element (with overhead)
// String memory
$str = ''; // ~24 bytes base
$str = 'hello'; // 24 + 5 bytes
// Object overhead
class Foo {}
$obj = new Foo(); // ~40 bytes minimum

Small dataset (n < 100):

  • Insertion Sort O(n²) - Simple, efficient for small data

Medium dataset (100 < n < 1M):

  • Quick Sort O(n log n) - Fast average case
  • PHP’s sort() - Optimized built-in

Large dataset (n > 1M):

  • Merge Sort O(n log n) - Predictable performance
  • Timsort (Python, Java) - Hybrid approach

Special cases:

  • Nearly sorted: Insertion Sort O(n)
  • Integer keys, small range: Counting Sort O(n + k)
  • Need stability: Merge Sort
  • Memory constrained: Heap Sort

Unsorted data:

  • Linear Search O(n) - Only option

Sorted data:

  • Binary Search O(log n) - Optimal

Frequent lookups:

  • Hash Table O(1) - Best average case
  • PHP associative array

Range queries:

  • Binary Search Tree O(log n)
  • Segment Tree O(log n)

Shortest path (unweighted):

  • BFS O(V + E)

Shortest path (weighted, non-negative):

  • Dijkstra O((V + E) log V)

Shortest path (negative weights):

  • Bellman-Ford O(VE)

All-pairs shortest path:

  • Floyd-Warshall O(V³)

Minimum spanning tree:

  • Prim’s O((V + E) log V) - Dense graphs
  • Kruskal’s O(E log E) - Sparse graphs
  1. Use appropriate data structure

    • Hash table for O(1) lookup
    • Heap for O(log n) min/max
  2. Avoid nested loops

    • O(n²) → O(n) using hash table
  3. Use binary search

    • O(n) → O(log n) for sorted data
  4. Memoization

    • O(2ⁿ) → O(n) for recursive problems
  5. Early termination

    • Break loops when answer found
  1. In-place algorithms

    • Modify input instead of creating new array
  2. Two pointers

    • O(n) space → O(1) space
  3. Iterative vs recursive

    • O(n) stack space → O(1) space
  4. Sliding window

    • O(n) → O(k) where k is window size
  5. Rolling hash

    • O(m) → O(1) for pattern matching

→ Hash table (PHP array)

→ Binary Search Tree or sorted array

→ Heap (SplPriorityQueue)

→ Queue (SplQueue)

→ Stack (SplStack)

→ Hash table O(n)

→ Two pointers O(n), O(1) space

→ KMP O(n + m) or PHP strpos() O(n)

→ BFS (unweighted) or Dijkstra (weighted)

→ PHP sort() O(n log n)

→ Token Bucket O(1) time, O(1) space → Sliding Window Counter O(1) time, O(k) space

→ HyperLogLog O(1) add, O(2^p) space → Bloom Filter O(k) add/check, O(m) space

→ Count-Min Sketch O(d) add/estimate, O(w×d) space

→ Worker Pool O(n/p) time, O(p) space → Async I/O O(1) scheduling, O(n) space

  1. ❌ Using in_array() in loop → O(n²) ✅ Use hash table → O(n)

  2. ❌ Multiple array_shift() → O(n²) ✅ Use SplQueue → O(n)

  3. ❌ String concatenation in loop → O(n²) ✅ Use array + implode() → O(n)

  4. ❌ Nested foreach without thinking → O(n²) ✅ Consider hash table approach → O(n)

  5. ❌ Sorting already sorted data repeatedly ✅ Check if sorted first or maintain sorted order

  6. ❌ Using array_shift() in sliding window → O(n²) total ✅ Use deque or circular buffer → O(1) per operation

  7. ❌ Storing entire stream in memory → O(n) space ✅ Use stream processing algorithms → O(1) or O(log n) space

  8. ❌ Exact counting for billions of items → O(n) space ✅ Use probabilistic algorithms (Bloom filter, HyperLogLog) → O(1) or O(log n) space

performance-testing.php
<?php
declare(strict_types=1);
function measureTime(callable $fn, mixed ...$args): float {
$start = microtime(true);
$fn(...$args);
return microtime(true) - $start;
}
function measureMemory(callable $fn, mixed ...$args): int {
$before = memory_get_usage();
$fn(...$args);
return memory_get_usage() - $before;
}
// Usage
$time = measureTime(fn() => myAlgorithm($data));
$memory = measureMemory(fn() => myAlgorithm($data));
echo "Time: " . number_format($time * 1000, 2) . " ms\n";
echo "Memory: " . number_format($memory / 1024, 2) . " KB\n";

Don’t optimize if:

  • Data size is small (n < 100)
  • Code runs rarely (batch jobs, migrations)
  • Code is clearer without optimization
  • Time saved is negligible

Do optimize if:

  • Data size is large (n > 10,000)
  • Code runs frequently (API endpoints, real-time systems)
  • User experience is affected (page load time)
  • Resource costs are high (server costs, memory)
Impact vs Effort
High Impact, Low Effort ← START HERE
├─ Replace in_array() with isset()
├─ Cache count() outside loops
├─ Use native sort() instead of custom O(n²)
└─ Enable OPcache
High Impact, High Effort ← DO AFTER QUICK WINS
├─ Implement caching layer (Redis/Memcached)
├─ Database query optimization
├─ Algorithm redesign (e.g., O(n²) → O(n))
└─ Data structure refactoring
Low Impact, Low Effort ← DO IF TIME PERMITS
├─ Code style improvements
├─ Minor refactoring
└─ Comment additions
Low Impact, High Effort ← AVOID
├─ Micro-optimizations
├─ Premature optimization
└─ Over-engineering

Example 1: E-commerce Product Search

product-search-optimization.php
<?php
declare(strict_types=1);
// ❌ BAD: O(n²) - checking duplicates in loop
$filtered = [];
foreach ($products as $product) {
if (!in_array($product->id, $filtered)) { // O(n) each time
$filtered[] = $product->id;
}
}
// With 10,000 products: 10,000² = 100M operations!
// ✅ GOOD: O(n) - using hash table
$seen = [];
$filtered = [];
foreach ($products as $product) {
if (!isset($seen[$product->id])) { // O(1) each time
$filtered[] = $product->id;
$seen[$product->id] = true;
}
}
// With 10,000 products: 10,000 operations (10,000x faster!)

Impact: Page load reduced from 5s to 50ms

Example 2: User Activity Feed

activity-feed-optimization.php
<?php
declare(strict_types=1);
// ❌ BAD: N+1 query problem
$posts = $db->query("SELECT * FROM posts LIMIT 50");
foreach ($posts as $post) {
$user = $db->query("SELECT * FROM users WHERE id = {$post['user_id']}");
$post['author'] = $user;
}
// 51 database queries!
// ✅ GOOD: Single JOIN query
$posts = $db->query("
SELECT posts.*, users.name, users.avatar
FROM posts
JOIN users ON posts.user_id = users.id
LIMIT 50
");
// 1 database query (51x fewer queries!)

Impact: API response time reduced from 800ms to 15ms

Example 3: Log Processing

log-processing-optimization.php
<?php
declare(strict_types=1);
// ❌ BAD: String concatenation in loop
$log = '';
foreach ($entries as $entry) {
$log .= $entry . "\n"; // Creates new string each time
}
// O(n²) time, O(n²) memory with 100,000 entries = 10B operations!
// ✅ GOOD: Array + implode
$lines = [];
foreach ($entries as $entry) {
$lines[] = $entry;
}
$log = implode("\n", $lines);
// O(n) time, O(n) memory with 100,000 entries = 100K operations

Impact: Memory usage reduced from 5GB to 50MB

Fundamentals:

  • Chapter 1: Introduction to Algorithms → Big O basics
  • Chapter 2: Time Complexity Analysis → Detailed complexity analysis
  • Chapter 3: Space Complexity → Memory usage patterns

Data Structures:

  • Chapter 4: Arrays and Lists → Array operations (this appendix)
  • Chapter 5: Stacks and Queues → Stack/Queue complexity
  • Chapter 6: Hash Tables → O(1) lookup patterns
  • Chapter 14: Heaps → Heap operations and Priority Queues
  • Chapter 16: Binary Search Trees → Tree operations
  • Chapter 17: Balanced Trees → AVL/Red-Black tree guarantees
  • Chapter 18: Tree Traversals → DFS/BFS complexity
  • Chapter 20: Balanced Trees (AVL & Red-Black) → Self-balancing tree operations

Algorithms:

  • Chapter 7: Linear Search → O(n) search
  • Chapter 8: Binary Search → O(log n) search
  • Chapter 9-13: Sorting Algorithms → Sorting comparison table
  • Chapter 19: Graph Representations → Graph storage complexity
  • Chapter 20-22: Graph Algorithms → DFS, BFS, Dijkstra complexity
  • Chapter 23: String Algorithms → Pattern matching complexity
  • Chapter 33: String Algorithms Deep Dive → Advanced string algorithms (Z-algorithm, Suffix Tree)
  • Chapter 25: Dynamic Programming → Memoization patterns
  • Chapter 31: Concurrent Algorithms → Parallel processing patterns
  • Chapter 32: Probabilistic Algorithms → Space-efficient data structures
  • Chapter 36: Stream Processing → Real-time algorithms

Optimization:

  • Chapter 29: Performance Optimization → Practical optimization
  • Appendix B: PHP Performance Tips → PHP-specific optimizations

Need O(1) lookup? → Chapter 6: Hash Tables → This appendix: Hash Table section

Need to sort efficiently? → Chapter 10: Merge Sort → Chapter 12: Quick Sort → This appendix: Sorting Algorithms table

Need shortest path? → Chapter 20: BFS (unweighted) → Chapter 22: Dijkstra (weighted) → This appendix: Graph Algorithms table

Need to optimize recursive algorithm? → Chapter 25: Dynamic Programming → This appendix: DP Problems table

Working with strings? → Chapter 23: String Algorithms → Chapter 33: String Algorithms Deep Dive (advanced) → This appendix: String Algorithms table

Processing data streams? → Chapter 36: Stream Processing Algorithms → This appendix: Stream Processing Algorithms table

Need space-efficient solutions? → Chapter 32: Probabilistic Algorithms → This appendix: Probabilistic Algorithms table

Need parallel processing? → Chapter 31: Concurrent Algorithms → This appendix: Concurrent Algorithms table

Start: I need to process data
├─ Known operation on standard data?
│ └─ Use this appendix to find complexity
├─ Custom algorithm needed?
│ ├─ Search problem?
│ │ ├─ Sorted? → Chapter 8: Binary Search
│ │ └─ Unsorted? → Chapter 7: Linear Search
│ │
│ ├─ Sorting problem?
│ │ └─ Chapter 9-13: Sorting Algorithms
│ │
│ ├─ Graph problem?
│ │ └─ Chapter 19-22: Graph Algorithms
│ │
│ ├─ Optimization problem?
│ │ └─ Chapter 25: Dynamic Programming
│ │
│ ├─ Stream processing?
│ │ └─ Chapter 36: Stream Processing Algorithms
│ │
│ ├─ Big data / space constraints?
│ │ └─ Chapter 32: Probabilistic Algorithms
│ │
│ └─ Need parallel/concurrent?
│ └─ Chapter 31: Concurrent Algorithms
└─ Performance issue?
├─ Algorithm complexity? → This appendix
├─ PHP-specific? → Appendix B
└─ Profiling needed? → Chapter 29
  • Chapter 1: Introduction to Algorithms
  • Chapter 2: Time Complexity Analysis - Deep dive into Big O
  • Chapter 3: Space Complexity - Memory usage analysis
  • Chapter 4: Arrays and Lists - Array operations
  • Chapter 6: Hash Tables - O(1) data structures
  • Chapter 8: Binary Search - O(log n) searching
  • Chapter 10-13: Sorting Algorithms - Complete sorting guide
  • Chapter 25: Dynamic Programming - Optimization techniques
  • Chapter 29: Performance Optimization - Real-world optimization
  • Chapter 31: Concurrent Algorithms - Parallel processing patterns
  • Chapter 30: Real-World Case Studies - Practical algorithm applications
  • Chapter 32: Probabilistic Algorithms - Space-efficient data structures
  • Chapter 33: String Algorithms Deep Dive - Advanced string matching
  • Chapter 36: Stream Processing Algorithms - Real-time data processing
  • Appendix B: PHP Performance Tips - PHP-specific optimizations
  • Appendix C: Glossary - Algorithm terminology