You may need to estimate the execution time of your code snippet. For example, if you have five ways to make a copy of a list object in Python, you need to choose a faster way.
What do you do? One way is to use the DateTime module to capture the start and end times of the task. Then calculate the difference between the two. However, this method is not efficient because background processes can distort estimates. So what’s an efficient way to estimate the execution time of a code snippet?
The Python timeit module is designed to do just that. This is useful for measuring the execution time of code snippets. Let’s how the timeit module works with examples.
What is timeit module?
The timeit is Python’s built-in module that you can use to estimate the execution time of your Python code snippet. We have used it several times in previous blog posts.
import timeit timeit.timeit(stmt='pass', setup='pass', number=1000000, globals=None, timer= )
- stmt: It is the code snippet that you want to measure. The default value is ‘pass’
- setup: It is usually the import statements that you don’t want to include in the code snippet when measuring the time.
- timer: the timer object which you don’t have to worry about as it will be set automatically.
- number: the number of times you want to execute the code snippet. The default value is 1,000,000.
- globals: You can pass the global namespace globals() so that the code snippet can use all the variables from the globals namespace.
(1) The following example uses a one-line statement as a code snippet. It calculates the square of all numbers from 0 to 50. Note that it takes about 16 seconds to square all numbers from 0 to 50 about 1 million times.
>>> import timeit >>> timeit.timeit(stmt="[i**2 for i in range(50)]") 16.153305899999395
To calculate the time required for a single run, you need to pass 1 to number parameter or divide 16 seconds by 1 million.
>>> timeit(stmt="[i**2 for i in range(50)]", number=1) 0.00003070000093430281
(2) Note that the timeit module runs in its own namespace. In the example below, we are trying to find the square root of all numbers from 0 to 50 using the math module, and the math module is imported into the main scope. The following code will result in a
NameError. The name `math’is not defined because the math module was not imported into the timeit area.
import math import timeit code = """ squares = [math.sqrt(i) for i in range(50)] """ timeit.timeit(stmt=code)
How to fix this? Of course, you can also include “import math” as part of your code snippet. However, you probably don’t want to include it in it because you just want to estimate the execution of the code that produces the square root of all numbers from 0 to 50 without using the import statement. There are two options: a) setup and b) global parameters.
a) The setup parameter: you can pass the import statement via the setup parameter. The statements in the setup parameter are executed only once and are not part of the code snippet.
>>> import timeit >>> code = """ ... squares = [math.sqrt(i) for i in range(50)] ... """ >>> timeit.timeit(stmt=code, setup='import math') 10.895839600000272
b) The globals parameter: The globals() is the built-in function that returns all the objects that are part of the global module. If you have imported the math module in the global scope by passing globals() to globals parameter you are making import math available to the code snippet.
>>> import math >>> import timeit >>> code = """ ... squares = [math.sqrt(i) for i in range(50)] ... """ >>> timeit.timeit(stmt=code, globals=globals()) 10.318579799999952
I hope that you now understand all the parameters of timeit method, mainly setup and globals parameters. Let’s see the other important methods available in timeit module.
Methods available on timeit module
Other than timeit() method, there are 2 more important methods available in timeit module.
timeit.repeat(): It works almost the same way as timeit.timeit() and the main difference is that it repeats timeit.timeit() n times as passed to repeat parameter.
>>> import timeit >>> code = """ ... squares = [math.sqrt(i) for i in range(50)] ... """ >>> timeit.repeat(stmt=code, setup='import math', repeat=3) [10.724541399998998, 9.994093399996927, 10.465739999999641]
timeit.default_timer(): The default timer is always time.perf_counter(). It returns the value (in fractional seconds) of a performance counter.
>>> import timeit >>> start_time = timeit.default_timer() >>> code = """ ... squares = [math.sqrt(i) for i in range(50)] ... """ >>> timeit.timeit(stmt=code, setup='import math') >>> stop_time = timeit.default_timer() >>> print("The execution time is:", stop_time - start_time) The execution time is: 10.00125609999668
The timeit module also provides the option to use the command-line interface. The syntax for the command-line interface is shown below-
python -m timeit [-n N] [-r N] [-u U] [-s S] [-h] [statement ...]
- -n N: the number of times you want to execute the code snippet
- -r N: the number of times you want the timeit() function to repeat
- -u U: a time unit for timer output; can select msec, sec, etc.
- -s S: the setup details that will get executed before the code execution
- -h: for help
- statement: The code snippet.
An example using the command-line interface: The below example estimates the time taken to calculate the squares of all integers between 0–50 using the command-line interface.
>>> (base) C:\Users\swath>python -m timeit -n 1000000 "[i**2 for i in range(50)]" 1000000 loops, best of 5: 16.2 usec per loop
What are %time and %%timeit in Python?
For Jupyter notebook users %timeit and %%timeit are the two popular commands for timing the code snippet. One of the advantages of using these magic methods is that you don’t have to import the timeit module as it will be done behind the scenes.
%time: line magic command for single line statement code following the command.
%timeit squares = [i**2 for i in range(50)]
15.3 µs ± 767 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit: cell magic command for multi-line code covering the one cell in Jupyter notebook.
%%timeit sq =  cu =  for i in range(1, 51): sq.append(i**2) cu.append(i**3)
37.4 µs ± 1.09 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In this article, you have understood the timeit module in Python and how you can use it to time the code snippets with examples. We have covered both the Python interface and command-line interface of using the timeit module. Also, we have covered %timeit and %%timeit magic functions that are popular in the Jupyter notebook for timing the code snippets.