VizTracer, more than a python profiler

Tian Gao
3 min readAug 28, 2020

My boss once told us, never optimize without profiling. That is very true in almost all cases. Without proper profiling, you may spend hours in optimizing and end up not improving your performance at all.

So, the first thing to optimize your code, is to find a good profiler.

There are a lot of options in the market, even when we only talk about python.

cProfiler, which is probably the most common profiler python programmers are using, is a built-in package that provides deterministic profiling. It basically hooks all the function entries/exits and tells you the time consumed for each function.

There are popular statistical profilers like py-spy as well. They sample at a certain frequency to peek the stack, so they’ll have statistical result about your call stack and have less impact on the program. Flamegraph is a common form of their report.

However, I’m going to talk about VizTracer today, another python profiler I developed recently.

Obviously, the first question would be, why do we need another profiler?

cProfiler and py-spy are both very good profilers, and they can help to solve many performance issues. However, they are both providing “summary” of your program. They tell you the total time consumed by one function or the summarize of your call stack. They are not able to show the details of the execution of your program. They can’t show you the timeline of your program.

Don’t get me wrong, summary is very helpful in many cases. But in other situations, we want more. We want the timing sequence of our function executed, we want the length of every function call, and we want a pretty front-end to visualize those, not a cold black-n-white console.

That’s the reason I started developing VizTracer.

VizTracer also hooks on function entires/exits, much like cProfiler, but it records every function entry/exit and display it using trace viewer, like this:

You will know how your program is executed in a timeline and see every single function call.

In some way, I would call VizTracer more than a profiler, it’s also like a debugger. As you can see the functions executed, you may find functions that are not supposed to run at some point, or missing functions some where. These can as well be the performance impact, which cProfiler and py-spy can’t not discover.

Yes, undoubtedly, VizTracer uses much more memory and disk space compared to summary profilers, and that’s trade off you have to make if you want more information.

However, you can tailor VizTracer to suit your usage using filters. You can

  • Ignore all the c functions, like built-ins
  • Exclude functions in certain files, or only include functions in certain files
  • Limit the maximum stack depth you want to trace
  • Ignore certain functions

Most of the filters do not even require you to change your source code at all.

Also, do you have moments when you really want to log something on your timeline and check value of some variables/objects, but it’s always difficult to figure out where your program is when you log those? VizTracer help with that, too.

VizTracer provides custom events so you can insert events in your code, and see it on the timeline in your report. For example, I have a demo to do a gradient descent, and log the cost in the loop, which you can find here with some other examples.

Yes, VizTracer not only helps you to profile your program, but also helps you to understand and debug your program.

I know you have some common questions about it, so I’ll answer directly:

  • It supports Python 3.6+ on Linux/MacOS/Windows, CPython only
  • Super easy to use, just install it through pip. No source code changes in basic usage
  • It supports native Multi-Threading, and Multi-Processing with some efforts.
  • Overhead is even smaller than cProfile, but it took a while to dump the report
  • Open source under apache 2.0 and currently under active development

Give it a try and raise an issue if you have questions or requests about it :)

--

--