The idea: count operations, not seconds

Big-O describes how the number of basic operations an algorithm makes grows with the input size n. Seconds depend on the machine; the count does not. The page runs six real algorithms on the same sorted array of n values. Each one counts its own basic operation, and a bar shows the count on a log scale: every 4 marks on the axis is 10,000 times more work.

Log-scale chart of operations against n from 1 to 64 for the six rows: 1, log2 n + 1, n, n log2 n, n(n-1)/2 and 2 to the n. The 2 to the n curve crosses the 1-second line (10 to the 8 operations) at about n = 27 and reaches 1.8 times 10 to the 19 at n = 64; n(n-1)/2 reaches 2,016
On a log scale the polynomial rows bend and level off; 2ⁿ is a straight line that crosses 1 second near n = 27.

The six rows

RowAlgorithmOne operation isCount
O(1)read a[5]one array read1
O(log n)binary search for a key bigger than every value (3n + 5, the worst case)one probe of a[mid]⌊log₂ n⌋ + 1
O(n)linear scan for the same keyone comparisonn
O(n log n)top-down merge sortone value written by a mergeabout n·log₂ n (exactly n·log₂ n when n is a power of 2)
O(n²)bubble sort without the early exitone comparisonn(n−1)/2
O(2ⁿ)check every subset: does it add up to the key?one subset checked2ⁿ

A row says counted when the page actually ran the code with a counter (up to a million operations), and formula when it would take too long, as bubble sort on a million values would. Where both exist they agree. Press Trace (for n up to 32) to watch the first few operations of each algorithm on the drawn array (Demo: n = 8, everything is fast).

What doubling n does

The quickest way to feel a growth rate is to double n and see what happens to the count (Demo: doubling n):

Table-like figure for n = 8 to n = 16: O(1) 1 to 1, same; O(log n) 4 to 5, plus 1; O(n) 8 to 16, times 2; O(n log n) 24 to 64, times 2.7; O(n squared) 28 to 120, times 4.3; O(2 to the n) 256 to 65,536, squared
Doubling n adds one probe to binary search but squares the number of subsets.

O(n log n) grows a little faster than ×2 because each value also passes through one more level of merging. O(n²) tends to ×4 (28 → 120 is ×4.3 because of the −1). O(2ⁿ) is squared: 2¹⁶ = (2⁸)².

From operations to time

The page assumes 10⁸ simple operations per second, about 10 ns each, which is the right order for a simple loop on one core. At n = 1000, bubble sort's 499,500 comparisons take 5 ms and merge sort’s 9,976 writes take 100 µs: 50× apart, and the gap grows with n. At a million values it is 1.4 hours against 0.2 seconds (Demo: n = 1000, n² vs n log n).

n2ⁿ subsetstime at 10⁸ ops/s
82562.6 µs
1665,536660 µs
324,294,967,29643 s
641.8·10¹⁹≈ 5,800 years
10001.1·10³⁰¹3.4·10²⁸⁵ years

A faster computer does not rescue an exponential algorithm: a machine 1,000 times faster only moves the 1-second point from n ≈ 27 to n ≈ 37 (Demo: 2ⁿ blows up).

Constants matter at small n

Big-O drops constant factors. Set O(n) cost to 100 operations per item (parsing, hashing, a cache miss) and the linear row becomes 100·n. At n = 8 that is 800 operations against bubble sort's 28, and at n = 32 it is 3,200 against 496: the "worse" algorithm wins. They meet at n = 201. At n = 1000 the linear scan is ahead 5×, and from there it only gets further ahead (Demo: constants matter). This is why real sorts switch to insertion sort for short ranges.

Line chart from n = 0 to 400 of 100 n and n(n-1)/2. n(n-1)/2 is lower until they cross at n = 201, then it grows above 100 n
Below n = 201 the quadratic count is smaller; above it, 100·n wins and keeps winning.

See the Sieve of Eratosthenes for n·ln ln n work against trial division's n√n / ln n on real counts.

Why log n grows so slowly and 2ⁿ so fast, with log₂ as the mirror image of 2ˣ: see Exponentials and Logarithms.

For amortized cost, where one slow push is paid for by many cheap ones, see the Dynamic Array.

To see where n log n and n1.58 come from in divide-and-conquer algorithms, see The Recursion Tree and the Master Theorem.

For the formal definitions of O, Ω and Θ with the constants c and n₀, see Big-O, Omega, Theta.

What the page leaves out

Real running time also depends on memory access, caches and branch prediction, so one "operation" is not always 10 ns. Big-O is an upper bound; the page shows exact counts for one input, and binary search and linear scan are shown in their worst case. Average-case and amortized analysis, Θ and Ω, and space complexity are not drawn. See also Sorting Race (two sorts side by side on the same array), Binary and Linear Search and Comparison Sorting.

On the mind map

This page on the Basics mind map · 12 pages in 5 branches · open it to see the whole map and test yourself in recall mode.