Taking Snapshots of the Call Stack Using Pyinstrument
00:00 In this lesson, you’ll install and use Pyinstrument to profile two functions that work together to find prime numbers in a given range.
00:10 Pyinstrument is a third-party statistical profiler for Python that shows you where your code spends its time across the whole call stack. It gives you a tree of function calls and takes snapshots while your program runs so you can see which functions were active and for how long.
00:30
This is done with less overhead compared to deterministic profilers. Pyinstrument makes it more practical to spot slow parts of your code compared to something like cProfile
, which just lists every function called without context.
00:47
To test out Pyinstrument, you have these two functions that help you find prime numbers within the range. The first function is is_prime()
. It takes in number
as an input and checks whether it’s prime or not.
01:01
First, it returns False
if the number is less than two. Then it checks divisibility from 2
up to number - 1
. If it does find a divisor, it returns False
, and otherwise, it returns True
.
01:15
The second function is find_prime_numbers()
, which is the main function you run. find_prime_numbers()
takes in two inputs: start
and end
, then it loops from start
to end - 1
.
01:29
It uses the is_prime()
function from before to check whether each number is prime or not. If that number is prime, it appends it to a list and finally, it returns the list of prime numbers.
01:44
Your task is to use Pyinstrument
to profile the find_prime_numbers()
function and identify where most of the time is being spent when checking for primes between one and a hundred thousand.
02:00
You could use Pyinstrument either in your command line or in a Python file. Here you’re using it in a Python file called py_
instrument_prime.py
.
02:09
You already have the is_prime()
and find_prime_numbers()
functions here. But since pyinstrument
is a third-party tool, you’ll need to install it first.
02:20
You can use any package manager like pip
, or uv
. I’m using pip
. pip install pyinstrument
02:32
And as you can see, it says "Requirement already satisfied"
because I’ve already installed it before. Usually it’s best to install third-party packages inside the virtual environment to keep your projects isolated and avoid conflicts.
02:47
But I use Pyinstrument all the time, so I’ve installed it globally to keep it handy. To start, you need to import Profiler
from pyinstrument
.
02:58
from pyinstrument import
Profiler
with a capital P
.
03:06
After your function definitions, you can use Profiler
as a context manager. So with Profiler(
here you can set the interval
parameter, which tells Pyinstrument how often to take a snapshot of the call stack while your program runs.
03:26
For example, setting interval=0.001
means it will take a snapshot every one millisecond. A typical value is between 0.001
and 0.1
seconds depending on how detailed you want the output and how long your program runs.
03:47
And after you close the parenthesis: as profiler:
.
03:53
Now you need to run the function you want to profile. In your case, it’s find_prime_
04:07
Okay, now outside the context manager, you can run profiler.print()
to actually view the results of the profiler.
04:18
Now head over to the terminal. Let’s clear the output and run this file: python py_instrument_
prime.py
.
04:47 Okay, now you can see the report showing you the call hierarchy of functions. Right away, this view is more informative than the default output from cProfile because it shows you the context of each function call.
05:02 This matters because the same function might be called from multiple places for different reasons, and this view helps you see exactly where and how time is being spent.
05:12
Your root function is module
, 14.73 seconds was spent here. This is your script’s total runtime. Then you have find_prime_numbers()
, 14.73 seconds again.
05:28
So this is all time spent finding primes. And finally, you have is_prime()
in line three, this is showing you 14.72 seconds. From this, you can conclude that almost all the time in your script was spent here in is_prime()
.
05:49
So if you were to optimize the performance of your script, you would have to deal with is_prime()
.
05:57 So to recap, Pyinstrument is a statistical profiler that takes snapshots of your program’s call stack at regular intervals while it runs. Instead of logging every single function call like cProfile, it samples what’s happening over time, giving you a high-level view of where most of the time is actually being spent.
06:17 You now know how to use Pyinstrument to profile your scripts and how to read the call hierarchy to see exactly where your code is spending time.
Become a Member to join the conversation.