Python Tips & Tricks - Measure the execution time of your Python Codes | Towards Data Science

As we start becoming proficient in a programming language, we aspire to not only deliver the end objective but also to make our programs efficient.
In this tutorial of Did you know series we will learn about a few Ipython’s magic commands which can help us time profile our Python codes.
Note that, for the purpose of this tutorial, it is recommended to use Anaconda distribution.
To check the execution time of a single line of python code, use %timeit. A simple example below to see how it works:
#### Simple usage of magics command %timeit%timeit [num for num in range(20)]#### Output1.08 μs ± 43 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Key notes:
Use %timeit just before the line of code to be profiled
It returns the average and standard deviation of code run time calculated over r number or runs and n number of loops within each run. In the above example, the list comprehension was evaluated for 7 runs with each run having 1 million loops (default behaviour). This took an average of 1.08 microsecond with a standard deviation of 43 nanoseconds.
One can customise the number of runs and loops while calling the magic command. The example is below for reference:
#### Customizing number of runs and loops in %timeit magic command%timeit -r5 -n100 [num for num in range(20)]1.01 μs ± 5.75 ns per loop (mean ± std. dev. of 5 runs, 100 loops each)
Using command options -r and -n, indicating # of runs and count of loops respectively, we have customised the time profile operation to 5 runs and 100 loops within each run.
This section takes a step forward and explains how one can profile a complete code block. By making a small modification to %timeit magic command, replacing single percentage (%) with double percentage (%%), one can profile a complete code block. A sample demonstration for reference below:
#### Time profiling the code block using %%timeit%%timeit -r5 -n1000for i in range(10):    n = i**2    m = i**3    o = abs(i)#### Output10.5 μs ± 226 ns per loop (mean ± std. dev. of 5 runs, 1000 loops each)
It can be observed that the average execution time of the for loop is 10.5 microseconds. Note that the same command options -r and -n are use to control the count of runs and # of loops within each run respectively.
Till now, we have only looked at summary stats when profiling single line of code or a complete code block. What if we want to evaluate the performance of each line of code within the code block? Line profiler package to the rescue!!!
Line_profiler package can be used to perform line by line profiling of any function. To work with line_profiler package, take the following steps:
Install package — The line profiler package can be installed with a simple call to pip or conda install. If one is using anaconda distribution for Python, using conda install is recommended
#### Installing line_profiler packageconda install line_profiler
Load Extension — Once installed, you can use IPython to load the line_profiler IPython extension, offered as part of this package:
#### Loading line_profiler's Ipython extension%load_ext line_profiler
Time Profile the Function — Once loaded, use the following syntax to time profile any predefined function
%lprun -f function_name_only function_call_with_arguments
Syntax details:
The call to line_profiler starts with keyword %lprun and is followed by command option -f
The command option is then followed by the function name and then the function call
For the purpose of this exercise, we will define a function accepting list of heights (in meter) and weight (in lbs) as inputs and converts these in to centimetre and kg respectively.
#### Defining the functiondef conversion(ht_mtrs, wt_lbs ):    ht_cms = [ht*100 for ht in ht_mtrs]    wt_kgs = [wt*.4535 for wt in wt_lbs]#### Defining the height and weight lists:ht = [5,5,4,7,6]wt = [108, 120, 110, 98]#### Profiling the function using line_profiler%lprun -f conversion conversion(ht,wt)---------------------------------------------------------------#### OutputTotal time: 1.46e-05 sFile: <ipython-input-13-41e195af43a9>Function: conversion at line 2Line #      Hits         Time  Per Hit   % Time  Line Contents==============================================================     2       1        105.0    105.0     71.9      ht_cms = [ht*100 for ht in ht_mtrs]     3       1         41.0     41.0     28.1      wt_kgs = [wt*.4535 for wt in wt_lbs]
Output Details:
Complete time profile is done in units of 14.6 microseconds (refer to the first line of output)
The table generated, has 6 columns:
Column 1 (Line #) — Line number of code (note that line # 1 is deliberately omitted from output as it was just the function definition statement)
Column 2 (Hits) — Number of times the line was called
Column 3 (Time) — Number of time units (each time unit is 14.6 micro seconds) spent on the line of code
Column 4 (Per Hit)- Column 3 divided by Column 2
Column 5 (%Time) — Of the total time spent, what % of time was spent on that particular line of code
Column 6 (Content)- Content of the line of code
One can clearly notice that conversion of height from meter to centimetre has taken almost 72% of the total time spent.
With the execution time of each line of code at our disposal, we can deploy strategies to make our code efficient. In our next 3 tutorials, we will share some best practices to help you make your codes efficient.
I hope this tutorial of Did you know series was informative and you learned something new.
Will try and bring more interesting topics in future tutorials. Till then:
HAPPY LEARNING! ! ! !