Why we count operations instead of seconds
Wall-clock time measures your laptop; growth rate measures the algorithm.
title: Why we count operations instead of seconds
summary: Wall-clock time measures your laptop; growth rate measures the algorithm.
difficulty: beginner
tags: big-o, complexity
Time an algorithm on your machine and you have measured your CPU, your cache, the JIT, and what else was running. Move the code to a server and every number changes. What does not change is how the work grows as the input grows — and that is what complexity analysis captures.
Count the dominant operation
Pick the operation that repeats most — a comparison, an array access, an arithmetic step — and count how many times it runs as a function of the input size n.
function containsDuplicate(items) {
for (let i = 0; i < items.length; i++) {
for (let j = i + 1; j < items.length; j++) {
if (items[i] === items[j]) return true; // the comparison
}
}
return false;
}
The inner comparison runs n-1, then n-2, then n-3 times, and so on. That sums to n(n-1)/2, which is n²/2 - n/2 comparisons.
Then throw away everything but the growth
Two rules do all the work:
- Drop constant factors.
n²/2andn²grow the same shape; hardware decides the constant, not the algorithm. - Keep only the fastest-growing term. In
n²/2 - n/2, then²dominates: at n = 1,000 it is a thousand times larger than thenterm.
What survives is O(n²).
Why this is the useful number
| n | O(n) steps | O(n²) steps |
|---|---|---|
| 100 | 100 | 10,000 |
| 10,000 | 10,000 | 100,000,000 |
| 1,000,000 | 1,000,000 | 1,000,000,000,000 |
A faster machine moves every row by the same small factor. Changing the algorithm moves you between columns. At scale, the exponent beats the hardware, every time.
The duplicate check above becomes O(n) with a Set — one pass, remembering what it has seen. That is not a micro-optimisation; it is a different column.