Measure elapsed time in Python

Compare Python timing functions, measure elapsed work with perf_counter, and avoid confusing nanosecond units with clock resolution.

Best practices
Python programming and application logging

Use time.perf_counter() to measure how long an operation takes. Subtract a reading taken before the work from one taken afterward; the difference includes time spent waiting or sleeping.

Time a block of code

import time

start = time.perf_counter()
result = sum(range(1_000_000))
elapsed = time.perf_counter() - start
print(f"Elapsed: {elapsed:.4f} seconds")

The clock's reference point is unspecified. Its readings are useful as differences, not as dates or timestamps for logs.

Choose a clock for the task

Function What it measures Typical use
perf_counter() A high-resolution performance counter, including sleep Elapsed operation time and small benchmarks
monotonic() Time from a clock that cannot go backward Deadlines and timeouts
time() Seconds since the Unix epoch Wall-clock timestamps
process_time() Process CPU time, excluding sleep CPU work rather than end-to-end latency

time.time() can jump when the system clock changes, so subtracting its readings is a poor choice for reliable durations. monotonic() and perf_counter() are not a universal low-precision/high-precision pair: CPython 3.13 and later use the same clock for both. Inspect the actual resolution with time.get_clock_info("perf_counter").resolution.

For timeout calculations, use the same monotonic clock for both readings:

started = time.monotonic()
# Perform the operation here.
elapsed = time.monotonic() - started

Wrap repeated measurements

import functools
import time

def timing(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        try:
            return func(*args, **kwargs)
        finally:
            print(f"{func.__name__}: {time.perf_counter() - start:.4f}s")
    return wrapper

@timing
def slow_function():
    time.sleep(0.01)

The finally block records elapsed time even if the function raises. This wrapper is for synchronous functions. To time a coroutine's execution, measure around await, not just around creating its coroutine object.

FAQ

Does perf_counter_ns() guarantee nanosecond accuracy? No. It returns integer nanoseconds and avoids floating-point precision loss; hardware and operating-system clock resolution still apply.

How do I find a slow line? cProfile reports function-level statistics. Use a line profiler when you need line-level measurements. For small implementation comparisons, use repeated timeit runs rather than trusting one elapsed-time sample.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting