Timing Your Python Code with Built-in Libraries
Sometimes you want to know why your code is slow. The process of determining the slowness is called profiling. In this article, you will look at using some of Python’s internal libraries to help you track down your slow code.
Using timeit
Python comes with a module called timeit. You can use it to time small code snippets. The timeit module uses platform-specific timing functions to provide the most accurate timings possible.
The timeit module has a command-line interface, but it can also be imported. We will start out by looking at how to use timeit from the command line. Open up a terminal and try the following examples:
What’s going on here? Well, when you run Python on the command line and pass it the “-m” option, you tell it to load a module and run it as the main program. The “-s” tells the timeit module to run setup once. Then it runs the code n times and returns the best average across the 3 runs. For these silly examples, you won’t see much difference.
Your output will likely be slightly different, as it depends on your computer’s specifications.
Let’s write a silly function and see if you can time it from the command line:
All this function does is cause an error that is promptly ignored. Yes, it’s another silly example. To run timeit on this code at the command line, you will need to import it into its namespace, so make sure your current working directory is the same folder as this script. Then run the following:
Here you import the function and then call it. Note that we separate the import and the function call with semicolons and that the Python code is in quotes. Now we’re ready to learn how to use timeit inside an actual Python script.
Importing timeit for Testing
Using the timeit module inside your code is also pretty easy. You will use the same silly script from before and show you how below:
Here you check to see if the script is being run directly (i.e. not imported). If it is, then you import timeit, create a setup string to import the function into timeit’s namespace and then we call timeit.timeit. You will note that we pass a call to the function in quotes, then the setup string. And that’s really all there is to it! Now let’s learn about how to write our own timer decorator.
Use a decorator
Writing your own timer is a lot of fun, too, although it may not be as accurate as using timeit in some use cases. Regardless, you’re going to write your own custom function timing decorator!
Here’s the code:
For this example, you import the random and the time modules from Python’s standard library. Then you create our decorator function. You will notice that it accepts a function and has another function inside of it. The nested function will grab the time before calling the passed-in function. Then it waits for the function to return and grabs the end time. Now you know how long the function took to run, so you print it out. Of course, the decorator also needs to return the result of the function call and the function itself, so that’s what the last two statements are all about.
The next function is decorated with our timing decorator. You will note that it uses random to “randomly” sleep a few seconds. This is just to demonstrate a long-running program. You would actually want to time functions that connect to databases (or run large queries), websites, run threads or do other things that take a while to complete.
Each time you run this code, the result will be slightly different. Give it a try and see for yourself!
Create a Timing Context Manager
Some programmers like to use context managers to time small pieces of code. So let’s create our own timer context manager class!
In this example, we use the class’s __init__ method to start our timer. The __enter__ method doesn’t need to do anything other then return itself. Lastly, the __exit__ method has all the juicy bits. Here we grab the end time, calculate the total runtime, and print it.
The end of the code shows an example of using our context manager, wrapping the function from the previous example in it.
Wrapping Up
Using your own creativity to time your code is fun, and you can learn a lot in the process. However, you will probably want to try out some of Python’s profiling packages at some point to really supercharge your profiling power. These packages can provide you with useful reports that show not just where your code is slow, but also what is causing your memory usage to increase too much!
Have fun and start profiling your code today.
Related Topics
Python has lots of profilers available to you, much more than simply timing your code. You can read about some of these profilers in this article:
Profiling Your Code in Python
Code is never perfect. You will find that when you write a lot of code, you will often need to go back to improve it. For example, let's say you create a web app and it becomes popular a few months after launch. Now that it's popular and handling a lot more requests, the app is running much slower under load.








