🎓 A1Learner
🔍

Python Performance & Profiling

Profiling is a stopwatch for code. Profiling shows where a program spends its time.

Time a tiny job

timeit runs the code many times. It returns the total time as a float.

import timeit
result = timeit.timeit("sum(range(100))", number=1000)
print(type(result).__name__)

Repeat the timing

repeat gives a list of timings. The list length is the repeat count you asked for.

import timeit
times = timeit.repeat("sum(range(100))", number=100, repeat=3)
print(len(times))

Check both ways agree

Two ways can give the same answer. The faster way is then the better shape.

def loop_sum(n):
    total = 0
    for i in range(n):
        total += i
    return total
print(loop_sum(100) == sum(range(100)))

Profile by function name

cProfile prints a table for the run. At this stage, read the function names in it.

import cProfile
def work():
    sum(range(100))
cProfile.run("work()")

Example

import cProfile
import pstats
import timeit

def loop_sum(n):
    total = 0
    for i in range(n):
        total += i
    return total

def work():
    loop_sum(100)
    sum(range(100))

loop_times = timeit.repeat(lambda: loop_sum(20000), number=20, repeat=3)
builtin_times = timeit.repeat(lambda: sum(range(20000)), number=20, repeat=3)

if min(builtin_times) < min(loop_times):
    print("Winner: built-in sum")
else:
    print("Winner: hand loop")
print("Runs per timing:", 20)
print("Timings taken:", len(loop_times), "and", len(builtin_times))

pr = cProfile.Profile()
pr.runcall(work)
stats = pstats.Stats(pr)
names = sorted({key[2] for key in stats.stats if key[2].isidentifier()})
print("Our functions seen:", names)

Key points

  • Profiling: measuring where a program spends its time.
  • Use timeit to time a small piece of code many times.
  • One timing can mislead you.
  • Repeat it and trust the ranking.
  • Use cProfile to list the functions a run called.
  • Slow shape: a hand loop often loses to a built-in doing the same job.
  • You measure first, then you fix the slow part.

In this example, timeit repeats each sum three times. Each timing runs the sum 20 times. The code compares the smallest timing from each list. It prints only which way won, never a time. The counts 20 and 3 come from the code itself, so they never change. Then cProfile records a short run of work. The last lines keep only plain function names from its records. That drops labels for built-ins and for the profiler itself.

Note

Timings change from run to run and from machine to machine.

Never trust one exact number.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

Your program feels slow. What should you do first?