Sonith Manakkat

Algorithms, part 1 of 129 min read11 visuals

Big-O: how we judge algorithms

What an algorithm is, why we count steps instead of seconds, and how Big-O describes the way work grows as a job gets bigger, with everyday pictures for each common class.

  • Count steps, not seconds, because steps do not depend on the computer
  • Big-O describes how the work grows as the job grows
  • Speed often costs memory, and Big-O hides constants and small inputs

Share on LinkedIn

Share
Reading level

Every other part of this series asks the same question: how much work does this method need? Big-O is the shorthand computer scientists use to answer it. This part builds the idea from everyday examples, shows the common classes as pictures, and then adds an Expert view to each section with the precise definitions.

What is an algorithm?

An algorithm is a precise recipe: a finite list of steps that takes some input and produces an answer. A recipe for tea is an algorithm. So is the way you find a word in a dictionary.

InputClear stepsOutputWork done
Every algorithm has the same shape.
Expert viewWhat makes a recipe an algorithm

A textbook algorithm is unambiguous, finite (it always stops) and correct for every valid input. We study two costs: time (how many basic operations it performs) and space (how much extra memory it uses). Both are measured as functions of the input size, usually written n: the number of items in a list, the number of characters in a text, and so on.

Count steps, not seconds

Why not just time the program? Because seconds depend on the machine, the language, what else is running, and luck. A fast laptop beats a slow one running a better method, which tells you nothing about the method.

Seconds

  • Changes with the computer and its load
  • Cannot be compared between machines

Steps

  • The same on any computer
  • Shows how work grows as the job grows
Two ways to measure.
Expert viewThe model behind step counting

Analysis usually assumes a simple abstract machine where each basic operation (compare, add, read or write one memory cell) takes one unit of time. Real machines differ, but the way the count grows with n carries over, which is why the results are so durable. The abstraction ignores effects such as caching, so measured timings still matter in practice (see the last section).

Big-O in plain words

Big-O answers: if the job gets bigger, how much more work do I do? Double the list. Does the work stay the same, double, quadruple? That growth pattern is the "class", and we write it with a capital O.

size of the job (n)work
The same job size on the left, very different growth on the right.
  • 1 (constant)
  • log n
  • n
  • n log n
  • n squared
  • 2 to the n
Expert viewThe formal meaning

We write f(n) is O(g(n)) when, for large enough n, f(n) never exceeds some constant multiple of g(n). So O(3n + 7) is simply O(n): constants and lower-order terms are dropped because they stop mattering as n grows. Strictly, Big-O is an upper bound. When a bound is tight in both directions the notation is Theta; people often say "Big-O" informally when they mean the tight bound, and this series does the same.

The common classes

Each class has an everyday picture. Read them from cheapest to most expensive.

  • O(1) constantLooking a name up through an index: the same effort however big the list
  • O(log n) logarithmicOpening a phone book in the middle and halving again and again
  • O(n) linearReading every page of a book once
  • O(n log n)Sorting a deck of cards by splitting and merging
  • O(n squared)Comparing every person in a room with every other person
  • O(2 to the n)Trying every combination of on and off switches
Six classes and what they feel like.
1Start1,000,000 namesThe whole book is still possible
2After 1 look500,000The middle name rules out half the book
3After 2 looks250,000Half of the half is gone
4After 10 looksabout 1,000Ten halvings divide by about a thousand
5After 20 looksabout 1One name is left: found

Takeaway. Halving again and again is why O(log n) stays tiny even for huge lists.

Halving a phone book of one million names: the pile shrinks fast, so about 20 looks are enough.

Now see the numbers. Counts are steps for a job of size n.

Classn = 10n = 1,000n = 1,000,000
O(1)111
O(log n)about 3about 10about 20
O(n)101,0001,000,000
O(n log n)about 33about 10,000about 20,000,000
O(n squared)1001,000,0001,000,000,000,000
O(2 to the n)1,024a number with about 300 digitsfar too large to write out
  • 20steps for O(log n)
  • 20 millionsteps for O(n log n)
  • 1 trillionsteps for O(n squared)
The gap at one million items.
Expert viewReading the classes carefully

Logarithms here are base 2, but the base only changes a constant, so O(log n) needs no base. Exponential cost, as in checking every subset of n items, doubles with every extra item, so it is practical only for very small n. Some problems have no known fast method, and a large area of computer science studies where the line falls between "fast enough" and "hopeless". Polynomial classes such as n squared and n cubed sit between the comfortable ones and the exponential ones.

Best, average and worst case

The same algorithm can behave differently on different inputs. Looking for a name by reading down a list, you might find it first (lucky) or last (unlucky).

  1. Best caseThe name is first: 1 look
  2. Average caseAbout halfway on average: roughly n / 2 looks
  3. Worst caseThe name is last or missing: n looks
Linear search for one name in a list of n names.
Expert viewWhich case do we quote?

The worst case is a guarantee: it will never be slower. The average case needs an assumption about how inputs are distributed, so state it. The best case is rarely useful alone. They can differ sharply: quick sort is O(n log n) on average but O(n squared) in the worst case, while merge sort is O(n log n) in all three. Naming which case a bound refers to is part of stating it precisely.

Time against space

Speed can often be bought with memory. Keeping a ready-made index lets you answer questions quickly, but the index takes room and must be kept up to date.

Less memory

  • Small footprint
  • More steps for each question

Less time

  • Answers come fast
  • Extra data stored and maintained
The classic trade-off.
Expert viewSpace complexity and amortised cost

Space complexity counts the extra memory beyond the input: merge sort needs O(n), while insertion sort needs O(1). Recursion also uses memory for its call stack.

Amortised cost is the average cost per operation over a whole sequence, even when single operations vary. A growable array that doubles its capacity when full occasionally copies everything (expensive), but over many appends the total copying is proportional to the number of appends, so each append is amortised O(1). It is a guarantee over a sequence, not a probability.

What Big-O hides

Myth

A lower Big-O class is always faster

Fact

Only for large enough inputs: constants and small sizes can reverse the order

Myth

Big-O tells you the running time in seconds

Fact

It tells you how the work grows, not how long it takes

A common misunderstanding.
Expert viewConstants, caches and small inputs

An algorithm taking 100n steps is O(n) and can lose to one taking n squared steps when n is below 100. Real machines also reward memory access patterns that stay close together, so two methods with equal step counts can run at different speeds. This is why practical sorting and searching code often combines methods and why profiling beats guessing. Big-O tells you what happens as n grows; measurement tells you what happens at the n you actually have.

Try it by hand

  1. Find the queen of hearts by readingCount the cards you turn over: that is O(n)
  2. Sort the deck, then halveOpen in the middle, keep the half that must hold it, repeat; count the looks
  3. Compare every pair among 8 cardsCount pairs: 28; try 16 cards and get 120
  4. Fill in the tablePredict the steps for 100 cards for each method
  5. Compare with the table aboveWhich class grows fastest?
Ten minutes with a pen and a deck of cards.

Big-O is not about how fast it is today, but how badly it hurts when the job grows.

Frequently asked questions

Is O(n) always faster than O(n squared)?

For large enough n, yes. For small n, constants can make the other one quicker.

Why do we drop constants like the 3 in 3n?

Because Big-O describes the shape of growth, and constants do not change the shape.

Does Big-O apply to memory too?

Yes. The same notation describes how memory use grows with the input.

Do I need this for everyday programming?

It helps you notice when a loop inside a loop will not scale, which is the most common surprise.

Back to all articles