Measuring execution time of code snippets in Jupyter Notebook
Start your free 7-days trial now!
Measuring execution times multiple times
To measure execution time of a single line:
%timeit 2 + 3
15 ns ± 0.85 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
To measure execution time of a single cell:
%%timeit2 + 34 + 5
14.9 ns ± 2.38 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Note that the number of trials performed by %timeit
will vary according to how long each trial takes. For instance, consider the following:
%timeit sum(range(100000))
2.34 ms ± 55.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
We see that this code ran only 100 times, while 2+3
ran 100 million times - the longer a code snippet takes for its execution, the smaller the number of trials is.
Measuring execution times once
If for some reason, you just wanted to measure the execution time just once, then use %time
instead:
%time 2 + 3
CPU times: user 3 µs, sys: 1 µs, total: 4 µsWall time: 16.7 µs
Again, for a block of code, use %%time
like so:
%%time2 + 34 + 5
CPU times: user 20 µs, sys: 10 µs, total: 30 µsWall time: 43.2 µs
Measuring execution time of each statement
We've seen that the %timeit
and %%timeit
magic functions are useful when we want to know the execution time of a single statement or a group of statements.
Sometimes we want to know how much time is getting spent on which parts of the program. In technical jargon, we call this profiling, and fortunately Jupyter Notebook provides an extremely easy way to profile our program - the %prun
magic function.
Here's an example:
from random import random
def sum_up(): arr = [] for i in range(10000000): arr.append(random()) arr.sort() return arr
%prun sum_up()
20000005 function calls in 10.679 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1 5.000 5.000 5.000 5.000 {method 'sort' of 'list' objects} 1 3.175 3.175 9.905 9.905 <ipython-input-1239-954f70834392>:3(sum_up) 10000000 0.943 0.000 0.943 0.000 {method 'random' of '_random.Random' objects} 10000000 0.787 0.000 0.787 0.000 {method 'append' of 'list' objects} 1 0.772 0.772 10.677 10.677 <string>:1(<module>) 1 0.002 0.002 10.679 10.679 {built-in method builtins.exec} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Here, our program has been broken down into 7 individual statements, which are sorted by the total time spent on each statement. We see that the sort()
method is the most time-consuming task here. Normally, we would use these results to spot code to optimise.