Skip to main content
Taught by Tech Leads

Master pipelines, cloud & AI to become an operational Data Engineer.

DataScientist.fr
Image de Measuring Execution Time with time and datetime - Practical Tutorial in Python
Python

Measuring Execution Time with time and datetime - Practical Tutorial in Python

Photo de Romain DE LA SOUCHÈRE

Tech Lead, CTO AXI Technologies

Published on 2 janvier 2025 · 8 min of reading

In a world where every second counts, mastering the art of time management has become essential. Whether to optimize performance or simply to keep up with a busy schedule, timers prove to be valuable tools. This article explores various ways to incorporate timers into your projects, guiding you through techniques ranging from creating your own timer to using context managers and decorators. Discover how these tools can transform your approach to productivity.

Timers

Timers in Python are essential tools for monitoring and optimizing the execution time of your code. They allow you to measure the duration of individual processes, which is crucial for identifying bottlenecks and improving efficiency. In this section, we will explore three main methods for implementing timers in Python.

Using time.time()

The simplest method for measuring time in Python is to use the time.time() function. This function returns the elapsed time in seconds since the epoch (January 1, 1970). Here’s how to use it:
python
This method is easy to implement, but it can be affected by the limited resolution of the operating system, making it less accurate for very short measurements.

Using timeit

The timeit module is designed to provide more accurate measurements by repeating the execution of code and calculating the average to reduce the impact of fluctuations. Here’s an example of using timeit:
python
With timeit, you can specify how many times the code should be executed, which is useful for obtaining reliable results. However, this method is generally more complex to set up than time.time().

Using datetime

Another approach is to use the datetime module to create time objects and calculate the difference between them. This method is particularly useful if you need a more readable time format or if you want to include dates in your measurements:
python
With datetime, the elapsed time is returned as a timedelta object, allowing you to obtain detailed information such as days, seconds, and microseconds.
Each of these methods has its own advantages and disadvantages depending on the context of use. It is crucial to choose the method that best meets your specific needs in terms of accuracy and simplicity.

Your first timer

Creating your first Python timer is an essential step to becoming more efficient in optimizing your code. In this section, we will build a simple timer using the time.time() function, and then we will explore how to integrate this functionality into a more complex program.

Setting up the timer

The first step is to set up a basic timer to measure the execution duration of a block of code. Here’s how to proceed:
python
This simple script encapsulates a function whose duration you wish to measure. It uses time.time() to record the time before and after executing the code.
With these tools, you are now equipped to efficiently monitor and optimize the execution time of your Python code. This skill is essential for ensuring the performance of your programs, especially in production environments where every millisecond counts.

A timer class

For a more modular and reusable approach to monitoring execution time, you can create a timer class. This will allow you to manage multiple timers within the same program and better structure your code.

Creating the Timer class

Let’s start by defining a Timer class that encapsulates the logic for measuring time:
python
This Timer class includes three main methods: start to start the timer, stop to stop it, and elapsed_time to calculate the time elapsed between the two.

Using the Timer class

Let’s see how to use this class in a program:
python
With this structure, you can easily create multiple instances of Timer to measure different parts of your program in parallel, which is very useful for complex applications.

Advantages of a timer class

Using a timer class offers several advantages:
  • Modularity: You can manage multiple instances independently, improving code readability and maintainability.
  • Reusability: The class can be imported and used in different projects without additional modifications.
  • Extensibility: You can easily add features, such as storing execution times in a file or integrating with monitoring tools.
By using a timer class, you can transform your time management into an integral and efficient part of your Python development.

A context manager

One of the most elegant ways to manage timers in Python is to use a context manager. This allows you to monitor the execution time of a block of code using the with keyword, making the code cleaner and more readable.

Creating a context manager

To create a context manager for a timer, you can use the Timer class we defined earlier and turn it into a context manager by implementing the special methods __enter__ and __exit__:
python
In this version of the timer, __enter__ starts the timer, and __exit__ stops it, then calculates and displays the elapsed time. The parameters exc_type, exc_val, and exc_tb are used to handle exceptions, if necessary.

Using the context manager

Let’s see how to use this context manager in a program:
python
By using the with block, you encapsulate the code you wish to measure, and the timer automatically takes care of starting and stopping the timing.

Advantages of the context manager

Context managers offer several advantages:
  • Simplicity: The code is more concise and avoids errors from manually starting or stopping the timer.
  • Exception handling: The with block manages exceptions, ensuring that the timer stops even if there’s an error in the monitored code.
  • Readability: The code is more readable and intuitive, making it easier to understand and maintain.
By using a context manager, you can easily and effectively integrate execution time monitoring into your Python projects, ensuring clarity and robustness of the code.

A decorator

Python decorators are powerful tools that allow you to modify the behavior of functions or methods. When it comes to measuring execution time, a decorator can simplify the process by automatically wrapping the code you wish to monitor.

Creating a timer decorator

To create a decorator that measures execution time, you can use the following function:
python
Here, timer is a decorator that takes a function as input and returns a new function wrapper. This wrapper function measures the time before and after executing the original function and displays the elapsed time.

Using the decorator

To apply this decorator to a function, use the @ symbol followed by the name of the decorator, just before the function definition:
python
With this approach, the function my_function is automatically wrapped by the decorator, meaning that each time you call it, its execution time is measured and displayed.

Advantages of the decorator

Decorators offer several advantages:
  • Automation: They automate the process of measuring time, eliminating the need to manually repeat the timing code.
  • Reusability: The decorator can be easily applied to any function without modifying its internal code.
  • Simplicity: Using @timer makes the code cleaner and easier to read, especially when applied to multiple functions in a project.
Decorators are an excellent solution for effectively monitoring execution time in your Python projects, providing a modular and elegant approach to code optimization.

Other timer functions

In addition to the methods we have covered, there are other functions and tools for measuring execution time in Python. These tools can be particularly useful in specific situations or when advanced features are needed.

Using perf_counter

The time module offers the perf_counter function, which is often more accurate than time.time(). This function is ideal for measuring short intervals, as it uses the most precise counter available on your system:
python
perf_counter is particularly recommended for performance measurements because it includes time spent while the system is idle.

Using process_time

If you are interested in the CPU time used by the Python process, process_time is the right function. Unlike perf_counter, it does not account for the time during which the program is idle:
python
This measurement is ideal for analyzing CPU resource usage in computationally intensive scripts.

Using third-party libraries

For more complex needs, there are third-party libraries such as cProfile and line_profiler. These tools provide detailed performance analysis:
  • cProfile: Provides an overview of program performance by listing the execution time of each function.
  • line_profiler: Offers even finer granularity by analyzing execution time line by line.
These tools are particularly valuable for optimizing complex applications and for precisely identifying lines of code that slow down your program.
Each method or tool has its own advantages and is suited to specific use cases. Choosing the right approach depends on the required accuracy and the context in which you are working, allowing you to optimize your Python projects effectively.

Conclusion

In conclusion, measuring execution time in Python is an essential skill for optimizing the performance of your programs. Whether you use simple functions like time.time() or more advanced tools like perf_counter, it is crucial to choose the approach that best fits your specific needs.

Summary of methods

We have explored several methods for implementing timers:
  • Basic timers with time.time() for ease of use.
  • Timer classes for increased modularity and extensibility.
  • Context managers for elegant and secure integration.
  • Decorators for efficient automation and reusability.
  • Advanced functions like perf_counter and process_time for precise measurements tailored to specific contexts.

Towards continuous optimization

Using these techniques will not only allow you to monitor execution time but also to identify bottlenecks in your code. Continuous optimization of your programs, through accurate performance analysis, is vital to ensuring the responsiveness and efficiency of your applications.
By integrating these tools into your workflow, you can transform your development approach, ensuring that each line of code is as efficient as possible. Thus, you will be better prepared to tackle performance challenges in your current and future projects.

Want to go further?

This topic is part of our Become a Data Analyst course. Browse the full programme, or get it by email.

Share with

Photo de Romain DE LA SOUCHÈRE

Romain DE LA SOUCHÈRE

Tech Lead, CTO AXI Technologies

Expert Data Engineering et Cloud, Romain affiche plus de 11 ans d'expérience, dont plusieurs années comme Lead Developer sur des solutions Smart Building haute performance. Il y a conçu et mis en production des moteurs de traitement capables d'absorber des centaines de milliers de données de capteurs par minute, ainsi que des bases clusterisées gérant plus de 10 millions de données dynamiques. Certifié Microsoft Azure DevOps Engineer Expert, il maîtrise aussi bien le développement back-end (Python, C#) que le DevOps (Docker, Kubernetes, Terraform) et les agents LLM. Formateur en Python, cloud, DevOps et IA générative appliquée, il forme avec une obsession : Amener chaque apprenant à concevoir et déployer des architectures réellement scalables en production.

» Learn More

Associated trainings

All our trainings
Image de la formation Become a Data Analyst
Become a Data Analyst
6 months
Intermediate
Guarantee