Three ways to measure the performance of your Python code

Erick McCollum | 31 Oct 2021

DISCLAIMER: The opinions expressed on this website are solely my own, and they are not associated with my employer, another person, or another organization in any way. All information on this website is provided "as is", without guarantee or warranty of any kind. Read the full disclaimer here.

Are you looking for ways to measure the performance of your Python code/applications?

Three popular ways to measure the performance of Python code are:

I will be discussing each of these three ways in more detail below.

Please note that all sample code used in this article may be found on my GitHub profile at the following link: code-samples/Python.

Using the time.perf_counter() function.

The time.perf_counter() function returns a performance counter value can be used to measure execution time of Python code. For example, to measure the execution time of a simple for loop, one could use code similar to the following:


    start_time = time.perf_counter()
    
    for i in range(10):
        print(i)
    
    end_time = time.perf_counter()
    execution_time = end_time - start_time
    print(f"The execution time is: {execution_time}")

Please note that the value returned by time.perf_counter() does not have a reference point. Therefore, one should always calculate the difference between two points when measuring execution time.

Using the timeit module.

The timeit module provides a simple way to measure the execution time of Python code. As a module, timeit provides has both a command-line interface as well as a callable function that can be used within code. I have included examples of each below, using the same simple for loop as in the previous example.

Command-line interface.

One could execute the following command to use the timeit command-line interface:


    $ python3 -m timeit 'for i in range(10): print(i)'

Callable function.

In order to use the timeit callable function, one could use code similar to the following:


    def test_fn():
        for i in range(10):
            print(i)

    timeit.timeit(lambda: test_fn(), number=10000)

Please note that the timeit.timeit() callable function does not have a default number of repititions. The number of repetitions must be provided when calling the function.

Using the profile and cProfile modules.

The profile and cProfile modules provide more in-depth statistics than time.perf_counter() and timeit. There are many ways to use the profile and cProfile modules. However, I have shared one example code snippet below which uses the same simple for loop as the previous examples:


    with cProfile.Profile() as pr:
        for i in range(10):
            print(i)

    pr.print_stats()

Running the above code snippet produces an output similar to the following:


    12 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 cProfile.py:117(__exit__)
       10    0.000    0.000    0.000    0.000 {built-in method builtins.print}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

Details and definitions of this output may be found on the profile and cProfile documentation page.

Additional resources.