Skip to content

Big-O notation explained in plain words

October 31, 2026 · 2 min read

Big-O notation describes how the work a piece of code does grows as its input grows. It ignores the speed of your computer and asks one question: if the data doubles, what happens to the steps?

Timing O(1), O(n) and O(n²)

This script runs three functions on lists of 1,000, 2,000 and 4,000 items and times each one.

import time

def first_item(items):          # O(1)
    return items[0]

def contains(items, target):    # O(n)
    for item in items:
        if item == target:
            return True
    return False

def has_duplicate(items):       # O(n²)
    for i in range(len(items)):
        for j in range(i + 1, len(items)):
            if items[i] == items[j]:
                return True
    return False

def timed(func, *args):
    start = time.perf_counter()
    func(*args)
    return time.perf_counter() - start

for n in (1000, 2000, 4000):
    data = list(range(n))
    print(f"n={n:<5} O(1): {timed(first_item, data):.6f}s  "
          f"O(n): {timed(contains, data, -1):.6f}s  "
          f"O(n²): {timed(has_duplicate, data):.6f}s")

Output (your times will differ, but the pattern won't):

Output
n=1000  O(1): 0.000001s  O(n): 0.000024s  O(n²): 0.018857s
n=2000  O(1): 0.000001s  O(n): 0.000049s  O(n²): 0.084608s
n=4000  O(1): 0.000002s  O(n): 0.000108s  O(n²): 0.340402s

What the numbers show

Call the input size n. Each time n doubles:

  • O(1), constant: the time stays flat. items[0] takes one step whatever the list size.
  • O(n), linear: the time roughly doubles. Searching for -1 never matches, so the loop checks every item.
  • O(n²), quadratic: the time roughly quadruples. A loop inside a loop compares every pair of items.

Big-O describes the shape of the growth, not exact seconds. That is why it drops constants: O(2n) is just O(n). For small lists the difference is invisible, but at a million items an O(n²) function is unusable.

Common mistake

Judging code by one timing on a small input. At n=1000 the O(n²) function ran in under 0.02 seconds, which feels fine. Time it at several sizes, as above, and watch how the result changes when n doubles.

Another trap is thinking Big-O gives the real running time. An O(n) function with heavy work per item can be slower than an O(n²) one on tiny inputs. Big-O tells you who wins as data grows.

Takeaway

Big-O is about growth: flat for O(1), proportional for O(n), squared for O(n²). Double your input, watch the time, and you can tell which one you have.