timeit

import timeit
Updated March 13, 2026 · Modules
performance timing benchmark stdlib

The timeit module is Python’s built‑in solution for measuring execution time of small code snippets with minimal overhead. It disables garbage collection, runs the code many times, and uses the most precise timer available on your platform (time.perf_counter). It can be used both as a command‑line tool and programmatically.

Key Functions

timeit.timeit()

Runs a given statement repeatedly and returns the total time taken (in seconds). By default, it runs the statement 1 million times.

import timeit

code = "sum(range(1000))"
elapsed = timeit.timeit(code, number=10000)
print(f"Total time: {elapsed:.4f} seconds")
# Total time: 0.0342 seconds

Parameters:

ParameterTypeDefaultDescription
stmtstr'pass'The code to time, as a string or callable
setupstr'pass'Code that runs once before the timing loop (e.g., imports)
timercallabletime.perf_counterThe timer function to use
numberint1000000How many times to repeat stmt
globalsdictNoneGlobal namespace in which to execute the code

Returns: float — total time in seconds for number repetitions.

If you pass a callable as stmt, the callable is invoked inside the timing loop. This avoids the overhead of compiling a string each iteration.

def compute():
    return sum(range(1000))

# Passing a callable is slightly faster
elapsed = timeit.timeit(compute, number=10000)

timeit.repeat()

Runs timeit() multiple times and returns a list of the individual timings. Useful for seeing variation across runs.

import timeit

times = timeit.repeat("sum(range(1000))", number=1000, repeat=5)
print(f"Times: {times}")
# Times: [0.0034, 0.0032, 0.0033, 0.0035, 0.0031]
print(f"Best: {min(times):.4f}s")
# Best: 0.0031s

Parameters:

ParameterTypeDefaultDescription
stmtstr'pass'Same as timeit()
setupstr'pass'Same as timeit()
timercallabletime.perf_counterSame as timeit()
repeatint5How many times to run the timing loop
numberint1000000How many repetitions per timing loop

Returns: list[float] — list of times (in seconds) for each repeat.

timeit.default_timer

The default timer function used by the module. On Python 3.3+ this is time.perf_counter, which provides the highest‑resolution clock available.

import timeit
print(timeit.default_timer is time.perf_counter)
# True

You can substitute a custom timer if needed, but perf_counter is almost always the right choice.

Command‑line Interface

timeit can be invoked directly from the command line, which is convenient for quick benchmarking.

python -m timeit "sum(range(1000))"
# 100000 loops, best of 5: 1.23 usec per loop

The module automatically chooses a suitable number of loops and repeats the measurement multiple times, reporting the best time. You can pass setup code with -s:

python -m timeit -s "import numpy as np" "np.sum(np.arange(1000))"

Common command‑line options:

OptionMeaning
-n NRun each measurement loop N times
-r RRepeat the measurement R times
-s SExecute setup code S before the timing
-pUse time.process_time() instead of perf_counter
-vPrint raw timing results (verbose)

Examples

Timing different algorithms

Compare the speed of a list comprehension versus a for loop.

import timeit

listcomp = "[i**2 for i in range(1000)]"
forloop = """
result = []
for i in range(1000):
    result.append(i**2)
"""

t1 = timeit.timeit(listcomp, number=1000)
t2 = timeit.timeit(forloop, number=1000)
print(f"List comprehension: {t1:.4f}s")
print(f"For loop: {t2:.4f}s")
# List comprehension: 0.045s
# For loop: 0.062s

Using a setup to import modules

Setup code runs once before the timing loop and is not included in the measured time.

import timeit

setup = "import math; x = 10"
stmt = "math.sqrt(x)"
time = timeit.timeit(stmt, setup=setup, number=1000000)
print(f"sqrt time: {time:.3f}s")
# sqrt time: 0.087s

Timing a function with arguments

Wrap the call in a lambda or use functools.partial.

import timeit

def power(base, exp):
    return base ** exp

# Using a lambda
t = timeit.timeit(lambda: power(2, 10), number=100000)
print(f"lambda: {t:.3f}s")

# Using a callable reference
t = timeit.timeit(power, setup="from __main__ import power", number=100000)
print(f"callable: {t:.3f}s")

Common Patterns

Best‑of‑five timing

When reporting results, it’s common to take the minimum of several repeats to reduce noise from system load.

import timeit

times = timeit.repeat("sum(range(1000))", number=1000, repeat=5)
best = min(times)
print(f"Best of 5: {best:.4f}s per {1000} loops")

Timing with a custom namespace

If your code relies on global variables, pass them via the globals parameter.

import timeit

my_list = list(range(1000))
time = timeit.timeit("sum(my_list)", globals={"my_list": my_list}, number=10000)

Comparing two snippets

Use timeit.repeat for both and compare the best times.

import timeit
import statistics

times_a = timeit.repeat("sum(range(1000))", number=1000, repeat=7)
times_b = timeit.repeat("sum([i for i in range(1000)])", number=1000, repeat=7)

print(f"A: min={min(times_a):.4f}, mean={statistics.mean(times_a):.4f}")
print(f"B: min={min(times_b):.4f}, mean={statistics.mean(times_b):.4f}")

Errors

IndentationErrors

If your multiline statement is not properly indented, you’ll get an IndentationError. Use explicit newlines (\\n) or triple‑quoted strings.

# Wrong
timeit.timeit("""
for i in range(10):
print(i)  # missing indent
""")

# Right
timeit.timeit("""
for i in range(10):
    print(i)
""")

NameErrors

If your statement references names that aren’t defined, you’ll get a NameError. Include the necessary definitions in the setup parameter or pass them via globals.

# Wrong
timeit.timeit("my_func()")  # my_func not defined

# Right
timeit.timeit("my_func()", setup="def my_func(): return 42")

OverflowError

If number is set too high (e.g., > 10⁹), the loop may cause an OverflowError. Use a smaller number and repeat the measurement instead.

See Also