Back to articles list Articles
9 minutes read

How to Measure Python Script Execution Times

Program timing can give you a lot of valuable information. Let’s talk about the best ways to measure execution times in Python.

In this article, we’ll show you how to measure the execution time of Python programs. We’ll introduce you to some tools and show you helpful examples to demonstrate how to measure the time of a whole program, a single function, or just a simple statement. At the end, you’ll be better able to understand how your code is working by timing it accurately.

If you want to understand how to work with dates and times in Python, our Python Basics: Part 3 course covers this topic. If you’re interested in more material at the beginner level, our Python Basics track includes this and two other interactive courses.

The goal in this article is to develop two different programs to calculate Fibonacci numbers and time them both. But before we get started, we need a brief lesson in mathematics.

The Fibonacci Sequence

The Fibonacci sequence is a beautiful and famous mathematical sequence that’s easy to understand and straightforward to compute. The sequence starts with two values: 0, and 1. Subsequent values are added recursively by simply summing the last two numbers in the sequence. The first 12 Fibonacci numbers are:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89

These numbers pop up all the time in mathematics and have real-world applications in many fields, including computer science, optics, and even financial analysis. Fibonacci numbers also appear in the natural world. This has given rise to the Fibonacci spiral, which is a good model for shapes from seashells to spiral galaxies.

The algorithm to compute the nth Fibonacci number looks like this:

F0 = 0, F1 = 1,

and

Fn = Fn-1 + Fn-2

for n > 1

Our goal is to write a Python implementation and time how long it takes to compute the nth Fibonacci number. Before you go on with this article, try to come up with an implementation for yourself. (As a hint, you’ll need an if-elif-else statement.) Keep in mind that the algorithm is recursive, which means you’ll need to call the function from within itself.

Two Python Implementations

Now we will develop two different implementations to compute Fibonacci numbers and measure the execution time of both. Start by opening your favourite IDE or text editor. Write the following program and save the file as fibonacci_v1.py:

def fib_v1(num):
    if num > 1:
        return fib_v1(num - 1) + fib_v1(num - 2)
    elif num == 1:
        return 1
    else:
        return 0

fib_v1(42)

In this program, we check the first two numbers of the sequence (0, 1) separately. If we don’t have one of these values, we sum the last two numbers of the sequence. The function calls itself multiple times to calculate each Fibonacci number in the sequence and is therefore quite slow.

The second implementation is shown below. Enter this into a new Python script and save it as fibonacci_v2.py:

def fib_rec(f1, f2, n):
    if n == 0:
        return f1
    else:
        return fib_rec(f2, f1 + f2, n - 1)

def fib_v2(num):
    return fib_rec(0, 1, num)

fib_v2(42)

The second implementation splits the calculation into two functions. The recursive function fib_rec() only calls itself once and is therefore faster than the first implementation.

The Linux/UNIX time Command

The first method for measuring the execution time of our Python scripts uses the UNIX time command. The details of this will vary depending on the distribution you’re using, since each distribution has a different default command shell. The most common shell on modern Linux distributions is the bash shell, but there are others (e.g. the Z shell (zsh), or the Korn shell (ksh)). For some relevant background reading, take a look at our article How to Open and Run Python Files in the Terminal.

To measure the time of execution of our scripts, execute the following command from your shell of choice:

	>>> time python fibonacci_v1.py

The output will vary depending on your shell, but it should show the execution time and some other information (such as time taken for both system and non-system calls). The time will vary depending on the computing power of your system, but it should be in the ballpark of about 30 – 90 seconds for most standard machines.

To get an idea of how much faster the second implementation is, use the time command to time the execution of the second script:

	>>> time python fibonacci_v2.py

The execution time of this version should be much faster – something like a fraction of a second.

The time method is useful to measure the execution time of the whole program from outside the program itself. But there could be cases when you want to measure the time using Python from within the program. We’ll take a closer look at that.

Python’s time Module

The time module is a part of the Python standard library, meaning it comes with the default installation of Python. It includes a bunch of handy time-related functions. The time.sleep() function is used for pausing the execution of a program. This could be useful for your next web scraping project, i.e. to avoid any errors if there’s a delay in loading the webpage. If you want to learn more about web scraping, check out our article Web Scraping with Python Libraries.

 

To time the execution of the script using the time module, you can use the time() function, which returns the elapsed time in seconds since the Unix time epoch (January 1, 1970, 00:00:00 UTC). For the second implementation of the Fibonacci number script, we place a timer before and after the function call. Edit the fibonacci_v2.py file so it looks like this:

import time

def fib_rec(f1, f2, n):
    if n == 0:
        return f1
    else:
        return fib_rec(f2, f1 + f2, n - 1)

def fib_v2(num):
    return fib_rec(0, 1, num)

t1 = time.time()
fib_v2(42)
t2 = time.time()
print('Elapsed time: {} seconds'.format((t2 - t1)))

We have imported the time module and defined it two times, t1 and t2. The difference between these two values gives us the elapsed time, which we print in the final line.

The usefulness of this method should be clear. First, you don’t need to rely on platform-dependent programs to measure time as we did in the first example. Second, you can place timers anywhere in your script to measure the execution time of different parts of your code. In this case, just define t1 and t2 on either side of the block of code where you want to measure the execution time.

If you run the modified version of the fibonacci_v2.py script, you’ll notice the elapsed time is printed as 0.0 seconds. The time is returned as a floating-point number, but not all systems provide time with a high precision.

The time module also has the time_ns() function. It’s similar to time(), but it returns time as an integer number of nanoseconds since the epoch. This, however, is system dependent and may or may not provide higher resolution. For the results of some timing experiments, see PEP 564. In our article How to Work with Date and Time in Python, we show another example of using the sleep() and time() functions.

The Preferred Method

We left the best to last. The Python standard library includes another module for timing small bits of code. This is the timeit module, which is a little more robust and avoids some common pitfalls with timing the execution of your Python code. The library can be used from the command line or within your script. To use it from the command line, do something like this:

	>>> python -m timeit "1+2"

The -m flag tells python to run the timeit module as a script. See PEP 338 for more details. This will run the statement ("1+2") many times and report the best time. When the command line interface is used, timeit automatically determines the number of repetitions and reports this along with the minimum time.

To time our fib_v2() function from the command line, we need to do the following:

	>>> python -m timeit "from fibonacci_v2 import fib_v2" "fib_v2(42)"

The output printed to the command line reports the best (i.e. the minimum) time and looks something like this:

	50000 loops, best of 5: 6.7 usec per loop

Note that usec means µsec, or microseconds.

This way, you can either run single statements or import a function and time that from the command line. It is also possible to time the execution of a function from within your script.

Once again, edit the file fibonacci_v2.py so it looks like this:

import timeit

def fib_rec(f1, f2, n):
    if n == 0:
        return f1
    else:
        return fib_rec(f2, f1 + f2, n - 1)

def fib_v2(num):
    return fib_rec(0, 1, num)

n = 50000
total_time = timeit.timeit('fib_v2(42)', number=n, globals=globals())
print('Average time: {} usec'.format((total_time/n)*1e6))

Here we’re using the timeit() function from the timeit module. The arguments are stmt, which is the function to execute; number, which is the number of times to execute the function; and the globals argument, which specifies the namespace in which to run the code. The globals() keyword returns a dictionary of all currently loaded modules and functions; specifying this gives us access to them. The returned value is the cumulative (not minimum) time. After calculating the average, the output looks something like this:

	Average time: 7.09615 usec

When run from the command line, the results are better (since the command line interface reports the minimum time by default). It's also worthwhile to note that there are advantages to using the timeit module as opposed to the time module. timeit is designed to obtain more accurate measurements of the execution time than those from the time module. The results are less likely to be impacted by external factors due to the operating system.

Now That You Know How to Measure Execution Time in Python …

Knowing how to properly measure the execution time of your Python functions and scripts is a useful tool. It allows you to understand how your programs are running. This could be particularly handy for computationally expensive programs, e.g. when you’re processing a lot of data.

To learn how to handle data properly, check out our Python for Data Science track, which includes 5 interactive courses. With another tool under your belt, you’ll be well on your way to becoming a Python master!