Profiling: Flame Chart vs. Flame Graph

Flame Charts and Flame Graphs clearly explained

--

Flame charts and Flame graphs are both techniques of visualizing profiling data. For many software engineers, they are the first visualizations we encounter when we first start doing performance work. If you’re a frontend engineer like myself, chances are the Flame chart is what you are most familiar with. Although Flame charts and Flame graphs look and sound similar, they are not the same.

Let’s say you have this Javascript function:

const planVacations = (n) => {
for (let i = 0; i < n; i++) {
const budget = makeBudget();
const dates = pickDates(budget);
chooseCity(budget);
bookHotel(budget, dates);
}
}

Here, you’re planning n vacations. For each vacation, you make a budget, pick dates, choose a city and hook a hotel based on that budget.

I created a simple React app and ran this code in the frontend with the Chrome Profiler on.

Where the “makeBudget” frames are

This is a Flame chart. Flame charts let you visualize what’s happening in your application on a time basis.

Flame Chart

Flame chart has time on the horizontal axis and the call stack on the vertical axis. In our example, we ran the same set of functions n times in the for loop. Thus, the same functions would appear n times in the Flame chart as different frames.

Each rectangle in a Flame chart is called a frame. The width of the frame represents the total time of the function. A function’s total time is time spent in the function itself and the time spent in all the functions that it calls. In contrast, a function’s self time is the time spent in the function itself, excluding the time spent in the functions that it calls.

total time vs. self time as visualized by frames

The functions with the most total time will always be at the top because a child’s total time cannot exceed its parent’s. A child’s self time on the other hand, can exceed its parent’s. Therefore, when you’re trying to do optimization work by cutting down on function time, you need to look for functions with the most self time.

In a Flame chart, a function’s self time is represented as the difference in width of its frame and the frames right below it.

By the way, in the screenshot above, you can also see where a recursion occurred in the code.

the Flame chart reveals bookHotel called itself many times.

Flame Graph

Like Flame charts, Flame graphs also use frames for visualization. The width of the frame also represents the total time of the function. What’s different is that Flame graphs don’t have a time component to it.

In our planVacations examples, the Flame chart looks like this:

Flame chart

By contrast, the Flame graph would look like:

Flame graph

The Flame graph merges the repeated frames created by the loop together, and order the frame alphabetically. This is why bookHotel appears before chooseCity even though timing wise, it comes after.

Flame Chart vs. Flame Graph: strengths & weaknesses

Flame Charts show the passage of time; therefore, they can reveal temporal patterns of the application. You can see loops for instance, in a Flame chart. However, because they show the passage of time, Flame charts cannot be used to display multi-threaded applications (without some next-level creativity). How would you picture the passage of multiple threads under a parent frame?

Temporal patterns and loops are hidden in a Flame graph. However, because Flame graphs do frame merging, they are better at showing a bigger picture of the profile. Additionally, because there’s no passage of time, Flame graphs can be used for multi-threaded applications.

Flame graph for multiple threads

Flame charts and flame graphs are just two of many ways to visualize profiling data. They are useful in different scenarios, but they both have similar weaknesses too. By themselves, neither of them are great at helping users identify functions with the most cumulative self time. This is because one function can appear in several places in the call stacks, and thus appear in multiple frames throughout the visualization. Neither Flame charts nor Flame graphs can help users with issues of concurrency in a multi-threaded system either. For these use cases, you need to look for other visualization tools like Call graph and Thread timeline, respectively.

Want to learn more? Read my blog post: “Surfacing performance issues with effective visualization of profiling data.”

I’m Lily Chen, senior software engineer on the profiling team at Datadog. If you like my work, I’d greatly appreciate some claps and a follow ❤

--

--