Topics: AI | Data Science | Data Visualization | Deep Learning | Machine Learning | NLP | Python | R | Statistics

KDnuggets Home » News » 2021 » Mar » Tutorials, Overviews » A Simple Way to Time Code in Python ( 21:n12 )

A Simple Way to Time Code in Python


Read on to find out how to use a decorator to time your functions.



By Edward Krueger, Senior Data Scientist and Tech Lead & Douglas Franklin, Aspiring Data Scientist and Teaching Assistant

Figure
Photo by Brad Neathery on Unsplash

 

Introduction

 
Our goal is to create an easy way to time functions in Python. We do this by coding a decorator with Python’s libraries functools and time. This decorator will then be applied to functions whose runtime we are interested in.

 

Timing Decorator: @timefunc

 
The code below represents a common decorator pattern that has a reusable and flexible structure. Notice the placement of functool.wraps. It is a decorator for our closure. This decorator preserves func’s metadata as it is passed to the closure.

Functools becomes significant on line 16, where we access func.__name__ in our print statement. If we did not use functools.wraps to decorate our closure, the wrong name would be returned.

This decorator returns the runtime of the function passed to timefunc(). On line 13, start initiates timing. Then, line 14's result stores the value of func(*args, **kwargs).After that, time_elapsed is calculated. The print statement reports func’s name and execution time.

 

Applying timefunc with the @ symbol

 
In Python, decorators can be easily applied with the @ symbol. Not all applications of decorators use this syntax, but all @ symbols are an application of a decorator.

We decorate single_thread with timefunc using the symbol.

Now that single_thread is decorated, when it’s called on line 13 we’ll see its func.__name__ and runtime.



Output of single_thread decorated by timefunc

 

If you want to know how this works, below we will go a little deeper into the why and how of coding a decorator to time functions.

 

Why One Might Time a Function

 
The reason is relatively straightforward. Faster functions are better functions.


Time is money, friend. — Gazlowe


The timing decorator shows us a function’s runtime. We can apply the decorator to several versions of a function, benchmark them and choose the fastest one. Additionally, it is useful to know how long executions will take when testing code. Got a five-minute runtime ahead? That's a nice window for getting up, moving your legs and refilling your coffee!

To write decorator functions in Python we rely on functools and an awareness of scope. Let's review scope and decoration.

 

Decoration, Closures and Scope

 
Decoration is a design pattern in Python that allows you to modify the behavior of a function. A decorator is a function that takes in a function and returns a modified function.

When writing closures and decorators, you must keep the scope of each function in mind. In Python, functions define scope. Closures have access to the scope of the function that returns them; the decorator’s scope.

It is important to preserve a decorated function's metadata as it is passed to a closure. Knowing our scope lets us properly decorate our closures with functools.wraps.

For more on these concepts read this three-minute piece.

Decorators and Closures by Example in Python
How to augment the behavior of a function using a decorator

 

On the reusability of this decorator

 
Notice that func is taken as an argument on line 7. Then on line 11, we pass *args, **kwargs, into our closure. These *args, **kwargs are used to calculate the result of func(*args, **kwargs) on line 10.

The flexibility of *args and **kwargsallow timefunc to work on almost any function. Our closure’s print statement is designed to access the functions __name__argskwargs and resultto create a useful timing output for func.

 

Conclusion

 
Decoration is a powerful tool to augment the behavior of functions. By coding a decorator to time your functions, you gain an elegant, reusable pattern to track a function’s runtime.

Feel free to copy timefunc into your codebase, or you can try coding your own timing decorator!

 
Edward Krueger is a Senior Data Scientist and Technical Lead at Business Laboratory and an Instructor at McCombs School of Business at The University of Texas at Austin.

Douglas Franklin is a Teaching Assistant at McCombs School of Business at The University of Texas at Austin.

Original. Reposted with permission.

Related:


Sign Up

By subscribing you accept KDnuggets Privacy Policy