Skip to content
BetaDE
Lesson 5 of 5Exploring computer science

Exploring computer science · Lesson 5 · 40 minutes

How fast is an algorithm?

What you'll learn

  • Count a program's steps instead of timing it
  • See how the number of steps grows when the data gets twice as big
  • Replace a slow algorithm with a fast one

Counting steps instead of timing

How fast a program is also depends on the computer. A new laptop is faster than an old one. That’s why computer scientists prefer to count steps. The question is: how many steps does an algorithm need when the data gets bigger?

In the Python lesson “Algorithms” you already saw that binary search manages with 20 steps where linear search needs a million. Here we look more closely at how the steps grow.

One loop: twice the data, twice the steps

To find the largest number in a list, you have to look at every number once. With twice as many numbers, it’s twice as many steps. That’s called linear:

def largest(items):
    steps = 0
    best = items[0]
    for number in items:
        steps = steps + 1
        if number > best:
            best = number
    return steps


for n in [10, 20, 40, 80]:
    print(f"{n:3} numbers → {largest(list(range(n))):3} steps")

Two nested loops: four times the steps

In a class, everybody should shake hands with everybody else once. With n people that’s n · (n − 1) / 2 handshakes. If you double the class, there are almost four times as many. That’s called quadratic:

def handshakes(n):
    steps = 0
    for a in range(n):
        for b in range(a + 1, n):
            steps = steps + 1
    return steps


for n in [10, 20, 40, 80]:
    print(f"{n:3} people → {handshakes(n):5} handshakes")

With 80 people it’s already 3160. With a million records it would be 500 billion steps – that takes far too long even for a fast computer.

Compared

Datalinearquadraticbinary search
1010454
1,0001,000499,50010
1,000,0001,000,000≈ 500 billion20

Computer scientists write O(n), O(n²) and O(log n) for this. The “O” means: this is roughly how the number of steps grows when n gets bigger.

Quick check

How many steps does this program count? Think first, then type.

steps = 0
for a in range(4):
    for b in range(4):
        steps = steps + 1
print(steps)

For the task: a look into a set (value in seen) only costs one step, no matter how big the set is. A look into a list, on the other hand, may have to check every element in the worst case. That’s exactly why the fast way is so fast.

Your task

Your turn

Find out whether a value appears twice in a list – in two ways, and count the comparisons. duplicate_slow(items) compares every pair once (two nested loops, the inner one starts after the outer one). duplicate_fast(items) remembers the values it has already seen in a set and counts every look into the set as one comparison. Both return a pair: (found, comparisons). As soon as a duplicate is found, both stop right away.

def duplicate_slow(items):
    comparisons = 0
    return False, comparisons


def duplicate_fast(items):
    comparisons = 0
    seen = set()
    return False, comparisons


numbers = list(range(1000))
print(duplicate_slow(numbers))
print(duplicate_fast(numbers))

Solve it without hints to earn a ⭐ on your progress page.

Show solution

Try it yourself first – mistakes teach you the most. Here is one possible solution:

def duplicate_slow(items):
    comparisons = 0
    for i in range(len(items)):
        for j in range(i + 1, len(items)):
            comparisons = comparisons + 1
            if items[i] == items[j]:
                return True, comparisons
    return False, comparisons


def duplicate_fast(items):
    comparisons = 0
    seen = set()
    for value in items:
        comparisons = comparisons + 1
        if value in seen:
            return True, comparisons
        seen.add(value)
    return False, comparisons


numbers = list(range(1000))
print(duplicate_slow(numbers))
print(duplicate_fast(numbers))