Understanding how fast a code is with Timeit

One may find her/himself creating scripts with initial and final instances of datetime.now(), executing a block of code in between them and then obtaining a delta between the two timestamps, in order to understand how long the code will take for its execution, or measuring performance between two or more approaches. I remember doing this in my early days of programming. It's not a bad approach: it actually works pretty well, but Python is a "batteries-included" language, with an extensive set of libraries available on its installation, like timeit, that will do the job for plenty of tasks that we come across.

Timeit does an excellent job, indeed. It executes a block of code N times and it repeats this loop R times as well, providing the best execution time while, for example, running a piece of code 100000 times, in 5 separated rounds of execution.


Running via Command Line

Here are some quick examples of how to use via command line.

Default values

Defining 10 rounds

Defining 10 rounds of 100000 executions


With this understanding, for example, we can compare the different methods of joining strings, and how efficient each one them can be:

Testing Module Functions and Comparing Approaches

Here's a more formal approach, testing a module and a couple of functions from it. I'm now comparing 3 different ways of joining strings, being it via concatenation or interpolation:


Seems that the first approach is more efficient, indeed. To my surprise, I've always thought that ''.join() would be more efficient than normal string concatenation. Worth to notice that each execution of timeit.repeat(), returns a list, that we can use as series for plotting on a chart, so we can have a more pictorial presentation of time differences between each approach.


MORE Comparisons...

Lists have different ways of being extended, incremented, etc. Let's review this too.

There isn't so much difference but, it's fair to say that extend() isn't the fastest method of extending a list. For better spotting the difference (which is pretty small in nanoseconds), let's plot these series on a chart.


Plotting

Just a couple of general settings for a Matplotlib chart, easily configured by looking at Matplotlib official documentation:



Here the results:

Indeed, incrementing is the most efficient method for extending a list.

But what about the joining of strings through concatenation or interpolation?

Here's an adaptation of the previous code, but using the string functions observed before:

And the difference in nanoseconds scale, is even bigger:

Any time difference represents a big difference, when we think about millions of executions of a instruction, even for the list extension methods. Using the most efficient method in order to achieve something, it's a practice to be maintained and it always pays off. But if the code isn't repeated so many times, it's ok to use whichever method you like, as long as the code is clean and objective (and documented, please),


Final Words


After using timeit, it's hard to think about other methods for measuring the time efficiency of blocks of code, or even small pieces of code. It's not intended to be a full profiler tool, but at least, gives you a clear perspective of how fast a approach or method can be, spotting minimal differences between similar approaches, and these small differences, will certainly represent more time consumption to your program, if the code is exposed to thousands of iterations.
Mastodon