Measure Python Code Speed with timeit

Published on: May 30, 2026
Reading time: 4 minutes
Medição de tempo de execução de código Python com timeit

Have you ever wondered why one piece of code takes longer than another, or whether a change actually improved performance? You need to learn how to measure code execution time with timeit. Efficiency in programming is not a luxury but a necessity. Small variations in how you write a loop or process a list can cause dramatic speed differences, especially on large datasets. Python provides a native, extremely precise tool for this job: the timeit module. Unlike simple manual stopwatches, this library is designed to eliminate distortions caused by background processes on the operating system, ensuring reliable results for micro-optimizations.

Why measuring execution time is essential

Many beginner developers rely purely on intuition to decide which function is faster. Intuition often fails when dealing with memory and processor complexity. Understanding your algorithm’s performance lets you identify bottlenecks before they become real production problems. When a system starts to scale, inefficient code can drive server costs up or deliver a poor user experience.

The measurement process also deepens your understanding of data structures. Comparing lookup time in a list versus a dictionary is a valuable practical lesson. The official Python documentation documents timeit as the standard tool for accurate micro-benchmarks.

What is the timeit module?

timeit is a standard library module created specifically to measure the execution time of small code snippets. It runs the code thousands (or millions) of times and computes the average, minimizing the impact of temporary CPU usage fluctuations. If you only use the Python time module with time.time(), you may get imprecise results due to clock resolution or external interruptions.

The major advantage of timeit is that it temporarily disables the garbage collector during measurement. This ensures that memory cleanup time is not unfairly charged against your code’s logic. It is the gold standard for anyone who wants serious, precise benchmarks.

Using timeit from the command line

One of the fastest ways to test an idea is directly in the terminal. You do not need to create a full script to check whether a list comprehension is faster than a traditional for loop:

python -m timeit "[x**2 for x in range(100)]"

Python will load the timeit module, execute the code snippet repeatedly, and return the average of the best time obtained across several loops.

Measuring code time inside a script

For in-script use, call timeit.timeit(). It accepts the code to test as a string (or a callable) and the number of repetitions. Let’s compare two ways to concatenate strings — the + operator and the join() method, which is generally recommended for better performance:

import timeit

# Code 1: Using + concatenation
code_plus = 's = ""; lst = ["item"] * 100nfor i in lst: s += i'

# Code 2: Using join
code_join = 'lst = ["item"] * 100; "".join(lst)'

time_plus = timeit.timeit(stmt=code_plus, number=10000)
time_join = timeit.timeit(stmt=code_join, number=10000)

print(f"Time with '+': {time_plus:.5f} seconds")
print(f"Time with join: {time_join:.5f} seconds")

The number parameter defines how many times the block runs. If not specified, the default is 1,000,000 iterations.

Using the setup parameter

Often the code you want to measure depends on variables or imports that should not be included in the measured time. The setup argument handles this — code inside setup runs only once before measurement begins:

import timeit

setup_code = "import math"
test_code = "math.sqrt(144)"

result = timeit.timeit(stmt=test_code, setup=setup_code, number=1_000_000)
print(f"Execution time: {result} seconds")

Comparing functions directly

Passing strings to timeit can be tedious and error-prone. A cleaner approach is to pass function references directly — especially useful when your functions are already defined in the script:

import timeit

def use_list_comp():
    return [str(i) for i in range(1000)]

def use_map():
    return list(map(str, range(1000)))

time_list = timeit.timeit(use_list_comp, number=10000)
time_map  = timeit.timeit(use_map,       number=10000)

print(f"List Comprehension: {time_list}")
print(f"Map Function:       {time_map}")

Using repeat() for more reliable results

A single measurement can be skewed by a sudden spike in system memory usage. timeit.repeat() runs the full measurement several times and returns a list of results for each round:

import timeit

times = timeit.repeat(stmt="sum(range(100))", repeat=5, number=100_000)
print(f"All times: {times}")
print(f"Best time: {min(times)}")

According to Wikipedia on code profiling, the minimum recorded time is generally the most reliable, as it represents the code running with the least possible system interference.

When to avoid timeit

timeit focuses on micro-benchmarks. If you need to analyze a complex system with database access or network API calls, most of the time will be spent waiting on external factors (I/O), making timeit results misleading. For profiling a full script or finding which function inside a large project consumes the most resources, a profiler like cProfile is more appropriate.

Benchmarking tips for accurate results

To get the best results, close other heavy programs while running tests, use enough repetitions so the total time is at least 0.2 seconds, keep tested functions pure (no print calls, which are slow and mask real calculation time), and use repeat() to spot inconsistencies across runs.

Frequently Asked Questions

Does timeit work with functions that take arguments?

Yes. Use a lambda or functools.partial to wrap your function with its arguments before passing it to timeit.

Why do timeit results vary slightly between runs?

Due to current OS load, Python memory management, and other processes running on the machine. That is exactly why using repeat() is recommended.

What is the difference between time.time() and timeit.default_timer()?

default_timer() automatically picks the best available clock for your platform (Windows or Linux), offering higher precision for short intervals.

Does timeit measure memory usage?

No, its exclusive focus is time. For memory measurement use memory_profiler or tracemalloc.

Does timeit disable the garbage collector automatically?

Yes, by default it disables garbage collection to make the CPU time measurement more isolated and consistent.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Como resolver erros com variáveis de ambiente usando python-dotenv
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Fix .env Errors in Python with python-dotenv

    Learn how to fix .env variable errors in Python using python-dotenv, load_dotenv, os.getenv, default values, find_dotenv, and API key security

    Ler mais

    Tempo de leitura: 4 minutos
    29/05/2026
    Leitura de variáveis de ambiente em projetos Python
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Read Environment Variables in Python Safely

    Learn how to read environment variables in Python safely with os.getenv, .env files, python-dotenv, validation, secrets, and deployment tips.

    Ler mais

    Tempo de leitura: 9 minutos
    21/05/2026
    Introdução ao uso de type hints em Python
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Python Type Hints: Write Cleaner Code

    Learn Python type hints with practical examples, function annotations, generics, Union, Optional, mypy, and best practices for cleaner code.

    Ler mais

    Tempo de leitura: 9 minutos
    21/05/2026
    Dicas para melhorar performance de scripts Python lentos
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Why Is Python Slow? Causes and Fixes

    Learn why Python can be slower than compiled languages, when it matters, and how to speed up your code with

    Ler mais

    Tempo de leitura: 9 minutos
    19/05/2026
    Proteção de API Flask usando autenticação JWT em Python
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Secure Flask APIs with JWT: Complete Guide

    Learn how to secure Flask APIs with JWT, access tokens, protected routes, expirations, refresh tokens, and production-ready best practices.

    Ler mais

    Tempo de leitura: 9 minutos
    19/05/2026
    Exemplo de testes unitários em Python com código de unittest para validação automatizada
    Best Practices
    Foto de perfil de Leandro Hirt da Academify

    Python Unit Testing: unittest, pytest & Mocks

    Writing automated tests is one of the most important skills modern Python developers can learn. While many beginners focus only

    Ler mais

    Tempo de leitura: 7 minutos
    09/05/2026