When to use Big-O analysis
Use Big-O when you want to:
- Compare two solutions before you write them, for example nested loops against a hash set.
- Predict whether code will cope with bigger input: "this works for 1,000 items, but will it work for a million?"
- Explain your solution in an interview: every answer should end with its time and memory cost.
- Spot the slow part of a design, such as a query that scans a whole table for every request.
Use something else when:
- You need the real running time on real hardware: measure it with a benchmark or a profiler. Big-O ignores constants, caches and the network.
- The input is always tiny (a dozen items). Then the simplest code wins, whatever its Big-O.
- You care about one slow request rather than growth: look at latency percentiles such as p99 instead.
There is nothing to import. Big-O is a way of describing code, not a library. Every language's documentation quotes it for its built-in lists, maps and sorts (see the real-world section).
How Big-O works
Big-O describes how the work (time) or the memory (space) of an algorithm grows as the input size, written n, grows. It does not measure seconds. It counts steps, such as comparisons, so the answer is the same on a laptop and a phone.
Keep only the part that grows fastest, and ignore constant factors.
3n + 10is O(n).n² + nis O(n²).
Why drop the rest? For a large n, the fastest-growing term swamps the others. At n = 1,000,000, n² is a trillion while n is a million, so the extra n changes almost nothing.
Here are the classes you will meet, from best to worst:
- O(1), constant. The work does not depend on
n: readingarray[i]. - O(log n), logarithmic. The problem is halved each step: binary search.
- O(n), linear. One pass over the data: summing a list.
- O(n log n), linearithmic. Halve the problem, but do a pass at each level: merge sort.
- O(n²), quadratic. A loop inside a loop over the same data: comparing every pair.
- O(2ⁿ), exponential. The work doubles with every extra item: trying every subset. Only usable for tiny
n.
Space complexity is the same idea for memory. It counts the extra memory the algorithm needs beyond its input, including the call stack of a recursive function.
Try it
Pick an input size, press Run, then step through. Each frame doubles n and shows how many steps each growth rate needs.
How work grows with input size
Step 1 of 5 · Press Space to play, arrow keys to stepInput size n = 1
Start with a single item. Every growth rate does about the same work here. Press Play and watch what happens as n doubles.
- input size n:
- 1
- linear steps:
- 1
- quadratic steps:
- 1
- exponential steps:
- 2
A step is one basic operation, such as one comparison. Bars are drawn to scale against the biggest non-exponential count; a red bar is off the chart.
Things to try:
- Small (8): at
n = 8the six classes take 1, 3, 8, 24, 64 and 256 steps. The first five are small, but exponential is already the biggest, and its red bar means it no longer fits the chart. - Medium (64): now quadratic takes 4,096 steps against 64 for linear and 6 for logarithmic. Watch the logarithmic bar barely move as
ndoubles. - Large (1,000): quadratic is 1,000,000 steps, while binary search needs 10. Exponential has been off the chart (the red bar) since about
n = 8, and byn = 64it cannot even be counted.
Big-O operations: working out the complexity
You do not need calculus. Read the code and apply a few rules.
- Steps one after another add. A loop of
nsteps followed by a loop ofnsteps isn + n = 2n, which is O(n). - Steps inside steps multiply. A loop of
ncontaining a loop ofnisn × n, which is O(n²). - Halving gives a logarithm. If each step cuts the remaining work in half, the number of steps is about
log2 n, which is O(log n). - Different inputs, different letters. Looping over list
aand then listbis O(a + b), and nested is O(a × b). Do not call bothn. - Recursion: count the calls and the work per call. A function that calls itself once with
n - 1doesncalls. One that calls itself twice withn - 1does about2ⁿ. - Space: count what you allocate. A new list of
nitems is O(n) memory. A recursion that goesncalls deep uses O(n) stack.
Three more ideas that interviewers ask about:
- Worst, best and average case. Quoted Big-O is usually the worst case. Searching a list for an item is O(1) if it is first, but O(n) if it is last or missing.
- Amortised cost. Appending to a dynamic array occasionally copies everything (O(n)), but doubling the capacity makes those copies rare, so the average append is O(1).
- Time against space. You can often buy speed with memory. Interview fact: a hash set turns an O(n²) duplicate check into O(n), at the price of O(n) extra memory.
Big-O time complexity
How many steps each class needs as n grows, and a familiar example of each.
| Class | n = 10 | n = 1,000 | n = 1,000,000 | Example |
|---|---|---|---|---|
| O(1) | 1 | 1 | 1 | Read array[i], push on a stack |
| O(log n) | about 4 | about 10 | about 20 | Binary search |
| O(n) | 10 | 1,000 | 1,000,000 | Find the largest item |
| O(n log n) | about 40 | about 10,000 | about 20,000,000 | Merge sort |
| O(n²) | 100 | 1,000,000 | 1,000,000,000,000 | Compare every pair |
| O(2ⁿ) | 1,024 | more than the atoms in the universe | not possible | Try every subset |
A rough rule of thumb is that a computer does about 100 million simple steps a second. So O(n²) is comfortable up to a few thousand items, O(n log n) up to millions, and O(2ⁿ) only up to about 25 items. If an interview problem allows n up to 100,000, an O(n²) answer will probably be too slow.
Big-O vs other ways to compare code
Big-O is one of several tools. n is the input size.
| What you want to know | Big-O | Benchmark (timing it) | Counting exact steps | Profiler |
|---|---|---|---|---|
| Which of two designs scales better | Yes, before writing it | Only after writing both | Possible but tedious | No |
| Real seconds on real hardware | No | Yes | No | Yes |
| Which function is the slow one | Only roughly | Slow to narrow down | No | Yes |
| Effect of caches, network, constants | No | Yes | No | Yes |
| Works in an interview, on paper | Yes | No | Sometimes | No |
Big-O wins when you are choosing a design on paper. It never replaces measuring: two algorithms with the same Big-O can differ by 10 times in real time.
How to explain Big-O in an interview
- State the variable. Say what
nis: "n is the number of ids", or "a is the rows and b is the columns". - Give both costs, every time. "This is O(n) time and O(1) extra memory." Mention the recursion stack if there is one.
- Name the worst case, then the typical case when they differ: "a hash set is O(1) on average, O(n) in the worst case."
- Show the trade-off. "I can get O(n) time with a set, or O(1) memory with nested loops. Given 100,000 ids I would take the set."
- Say why, not just what. "It is O(n²) because the inner loop runs about n times for each of the n outer iterations."