← Programming Fundamentals That Actually Matter
Lesson 2 of 10

Big O Notation: Why Your Code Gets Slow

SoftwareBeginner

Not About Speed. About How Speed Changes.

Big O describes how an algorithm's running time (or memory use) grows as the input grows - not how fast it runs on your laptop today, but what happens when today's 100 items becomes next year's 100,000. Two functions can both feel instant on a small list and behave completely differently once real data shows up.

javascript
// O(n) - one pass through the list
function findUser(users, id) {
  for (const u of users) {
    if (u.id === id) return u;
  }
}

// O(n^2) - a loop inside a loop
function findDuplicates(items) {
  const dupes = [];
  for (let i = 0; i < items.length; i++) {
    for (let j = i + 1; j < items.length; j++) {
      if (items[i] === items[j]) dupes.push(items[i]);
    }
  }
  return dupes;
}

O(1) constant, O(log n) logarithmic, O(n) linear, O(n log n), O(n^2) quadratic, O(2^n) exponential - roughly in order from "scales fine forever" to "unusable past a few thousand items." A hash map lookup is O(1). Sorting is typically O(n log n). Nested loops over the same data are usually O(n^2).

Where this actually bites people: a nested loop over a database result set that works fine in testing with 20 rows, then times out in production against a table with 500,000 rows. The fix is almost never "make the loop faster" - it's restructuring the algorithm (a hash map instead of a nested search, a database index instead of scanning every row) so the growth curve itself changes.