Post

Flamegraphs With Rust

Uncover Performance Bottlenecks with Rust Flamegraphs

Flame Graphs: A Visual Insight into Your Rust Applications

Flame Graphs are not just images; they are interactive SVG files that provide an in-depth view of your application’s performance. These visualizations are based on call stack samples taken at quantized moments, allowing you to statistically analyze how your program spends its time. Each function call within the stack is represented, and samples with the same call stack are grouped together to show a time distribution based on the width of each function call. In other words, Flame Graphs help you pinpoint which functions consume the most time in your application.

Using Cargo to create a flamegraph

To create a Flame Graph, you need an application that runs long enough to be effectively sampled and provides insights into its behavior. Let’s work with a simple code example:

Code Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use core::time::Duration;
use std::thread;
fn main() {
    for _ in 0..1000 {
        f1();
        f2();
        f3();
    }
}

fn f1() {
    thread::sleep(Duration::from_millis(10));
}
fn f2() {
    thread::sleep(Duration::from_millis(20));
}
fn f3() {
    thread::sleep(Duration::from_millis(30));
    f4()
}

fn f4() {
    thread::sleep(Duration::from_millis(40));
}

This code allows us to observe how execution time is divided between functions. In a real application, this would help identify bottlenecks or time-consuming functions. The functions primarily consist of sleep statements, making it easy to control the visualization.

Getting Started

Install cargo-flamegraph

1
cargo install flamegraph

Install linux-perf:

Compiling with Cargo

Now, let’s create a new project using Cargo:

1
2
3
4
cargo new perf_bench
cd perf_bench
cargo run
cargo flamegraph

Flamegraph Visualization

The resulting Flame Graph shows a hierarchy of function calls, representing the execution time distribution:

  • At the bottom is the name of the executable, which is the same as the project name.
  • Moving up the stack, you can see the “main” function, along with “f1”, “f2”, “f3”, and the nested “f4” call, as expected.
  • Within these functions, you’ll find the respective calls to the sleep function.

Notice the botton having the executable name which is the same name of the project and then going up in the call stack, main can be seen as well as f1…f3 and the nested f4 call, just as expected within them the respective calls to the “sleep” function.

This visual representation of execution time along the call stack is incredibly helpful for gaining insights into performance bottlenecks and optimizing your application.

Additional Resources

For more information on Flame Graphs, check out the following resources:

Explore your Rust application’s performance with Flamegraphs and uncover hidden bottlenecks for more efficient code. For the full code and more details, visit the project’s Github_repository

This post is licensed under CC BY 4.0 by the author.