Have you ever wondered how long it takes for your Python code to run? Or have you wanted to compare the performance of different approaches to solving a problem?
If so, you’ll need to know how to time your Python functions.
You can time Python functions using the time module, the timeit
module and profiling tools.
4 Common Ways to Time a Function in Python
Time.perf_counter()
Time.time()
Timeit
moduleCprofile
andprofile
By the end of this guide, you’ll have a good understanding of how to measure the elapsed time of your Python code, and you’ll be able to use the appropriate method for your specific needs.
4 Methods to Timing Functions in Python
There are four common methods to time a function in Python, including: time.perf_counter()
, time.time()
, timeit
and cprofile
or profile
. Let’s look at each one.
1. Time.perf_counter()
The time.perf_counter()
function is a high-resolution timing function that uses the processor’s performance counter to measure time.
It’s suitable for measuring the time taken by a function and the time taken by small code blocks or individual statements.
To use this function, you can call time.perf_counter()
before and after the code you want to time, subtracting the start time from the end time to get the elapsed time.
One advantage of perf_counter()
is that it’s based on a monotonic clock, which always increments and never goes backward. This makes it more suitable for measuring the elapsed time of a process or event.
2. Time.time()
The time.time()
function returns the current time in seconds since the epoch. The epoch is a predefined point in time, usually the beginning of the year 1970.
It’s not as precise as perf_counter()
, but it can be useful for timing longer-running functions or scripts.
One potential disadvantage of time()
is that it’s based on the system clock, which can be adjusted by the user or the system administrator, so the clock can go backward if the system time is changed.
3. Timeit Module
The timeit
module provides a simple way to time the execution of small bits of Python code.
It can be used to time a single function by wrapping it in a timeit.Timer
object and calling the timeit()
method.
One advantage of the timeit
module is that it allows you to specify the number of times the function should be run, which can help return more accurate timing results.
4. Profiling Tools
If you want to get more detailed information about the performance of your code, you can use a profiling tool such as cProfile
or profile
.
These tools can provide detailed statistics about the time taken by different parts of your code, the number of function calls and the amount of memory used.
Profiling tools can be particularly useful for identifying bottlenecks in your code and optimizing the performance of your application.
There are still many other ways to time functions, using datetime.datetime.now()
, time.clock()
, time.process_time()
, etc, but we’ll focus on the above four for now.
Timing Functions in Python With Example Code
Let’s test the methods on the following function.
def fibonacci(n):
"""Calculate the nth Fibonacci number using recursion."""
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
1. perf_counter()
import time
start = time.perf_counter()
result = fibonacci(20)
end = time.perf_counter()
elapsed = end - start
print(f'Time taken: {elapsed:.6f} seconds')
Time taken: 0.002537 seconds
2. time.time()
import time
start = time.time()
result = fibonacci(20)
end = time.time()
elapsed = end - start
print(f'Time taken: {elapsed:.6f} seconds')
Time taken: 0.002808 seconds
3. Timeit
import timeit
timer = timeit.Timer(lambda: fibonacci(20))
elapsed = timer.timeit(1)
print(f'Time taken: {elapsed:.6f} seconds')
Time taken: 0.002818 seconds
4. Cprofile
import cProfile
cProfile.run('fibonacci(20)')
21894 function calls (4 primitive calls) in 0.005 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
21891/1 0.005 0.000 0.005 0.005 4282974425.py:1(fibonacci)
1 0.000 0.000 0.005 0.005 <string>:1(<module>)
1 0.000 0.000 0.005 0.005 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Based on the output, ncalls
tells us the function was called 21,891 times, the total time spent was 0.005, and the average time spent per call was 0.000 seconds.
Now that you’ve seen the code samples, you’re probably wondering which method should you use?
Best Method to Time a Function in Python
When you’re deciding which method to use to time a function in Python, it’s important to consider the code and what you want to measure. Let’s take a look at when to use each of the methods.
Perf_counter() vs. Time()
Let’s reiterate the differences between perf_counter() and time().
time.perf_counter()
uses the processor’s performance counter to measure time, whiletime.time()
uses the system clock. In general,perf_counter()
is more precise and has a higher resolution thantime()
, so it’s often the better choice for timing small code blocks or individual statements.time.perf_counter()
is based on a monotonic clock, which means that it always increments and never goes backward. This makes it more suitable for measuring the elapsed time of a process or event. On the other hand,time.time()
is based on the system clock, which can be adjusted by the user or the system administrator. So, the clock can go back if the system time is changed.
If you want to measure the elapsed time of a process or event and you need high precision and a monotonic clock, time.perf_counter()
is the best choice.
On the other hand, if you need to measure the elapsed time of a longer-running script or function, and precision is not as important, time.time()
may be sufficient.
Use Timeit for Small Bits of Code
You might use the timeit
module when you want to quickly and easily time the execution of small bits of Python code. It’s particularly useful when you want to compare the performance of different approaches to solving a problem or when you want to optimize a specific piece of code.
Use Profile for Performance
You might use profiling tools when you want to get a detailed understanding of the performance of your code. Profiling tools can provide information about the time taken by different parts of your code, the number of function calls and the amount of memory used. This can help identify bottlenecks and optimize your code.
For example, suppose you have a large Python script that is running slowly, and you want to find out which parts of the code are taking the most time.
The output of cProfile
will show you a breakdown of the time taken by each function in your script, as well as the number of times each function was called. You can use this information to identify which functions take the most time and focus your optimization efforts on those functions.
Decorator to Time Functions Explained
To quickly time functions that you write, you can write a decorator that uses the perf_counter()
function.
Then for any function you define, you just have to include the @timeit
and it will show how long it took to run that function.
Below, the timeit
decorator is defined, and is added to the calculate_pi
function.
The calculate_pi
function approximates the value of pi using the Monte Carlo method. It generates n
random points in a unit square and counts the number of points that fall inside the unit circle inscribed within the square. The value of pi is then calculated as the ratio of the number of points inside the circle to the total number of points, multiplied by four.
import time
import random
def timeit(func):
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
end = time.perf_counter()
elapsed = end - start
print(f'Time taken: {elapsed:.6f} seconds')
return result
return wrapper
@timeit
def calculate_pi(n):
"""Calculate and return an approximation of pi using the Monte Carlo method."""
inside = 0
for i in range(n):
x = random.uniform(-1, 1)
y = random.uniform(-1, 1)
if x ** 2 + y ** 2 <= 1:
inside += 1
pi = (inside / n) * 4
return pi
pi = calculate_pi(1000000)
Time taken: 0.705406 seconds
At the bottom, when we call calculate_pi
, it shows us it took 0.7 seconds to run.
Timing Python functions is a useful skill to have in your toolkit as a developer.
Whether you’re optimizing code for performance or simply want to understand how long it takes for your code to run, several different methods are available to help you measure the elapsed time of your Python functions.
We’ve covered four of the most common methods in this guide: using the time
module, the timeit
module and profiling tools. Now, it’s your turn to put this knowledge into practice.
Try timing some Python functions using the different methods we’ve discussed, and see how they compare.
Frequently Asked Questions
How do you time a function in Python?
If you want to measure how long it takes for your code to run or compare the performance of different code approaches, there are four common approaches you can take in Python, including:
time.perf_counter()
time.time()
Timeit
CProfile
orprofile
What is the best way to time a function in Python?
The best method for timing a function in Python depends on your task.
Time.perf_counter()
is based on a monotonic clock, which means that it always increments and never goes backward. It’s best for measuring the elapsed time of a process.Time.time()
uses a system clock, which makes it more useful for measuring small blocks of code.Timeit
can quickly return the time it takes for small blocks of code to run, making it useful for comparing different approaches.CProflie()
returns detailed analysis of how much time each function takes to process in your code, which makes it best for code optimization tasks.