Rust Profiling
A profiler is a tool that watches a running program and reports which functions ate the time. A profiler names the real slow spot.
Build for profiling
Keep release speed, but keep the line information a profiler needs:
// Cargo.toml
[profile.release]
debug = "line-tables-only"Record with samply
samply runs your program and opens a visual profile in the browser:
samply record ./target/release/my_appOn Linux: perf plus a flame graph
perf records the samples, cargo flamegraph draws them:
perf record -g ./target/release/my_app
cargo flamegraphHunting allocations with DHAT
When the question is "who keeps allocating?", DHAT counts every allocation and names the line:
valgrind --tool=dhat ./target/release/my_appExample
fn count_letters(text: &str) -> usize { text.chars().filter(|c| c.is_alphabetic()).count() }
fn count_words(text: &str) -> usize { text.split_whitespace().count() }
fn main() {
let mut text = String::new();
for _ in 0..10_000 { text.push_str("rust makes fast programs "); }
println!("words = {}", count_words(&text));
println!("letters = {}", count_letters(&text));
println!("bytes = {}", text.len());
}Key points
- Profiler: a tool that watches a running program and reports where the time or memory went
- Profile a release build: a debug build has different hot spots and teaches the wrong lesson
- Sampling profiler: it checks what the program is doing many times a second
- It builds the picture from samples
- samply and perf work this way
- Use cargo flamegraph to draw the picture as a flame graph
- The wider a function's box, the more time it is eating
- Its calls count towards that time, too
- Use DHAT when allocations are the question: it reports exactly which lines allocated, how often, and how much
- The Rust Performance lesson set the rule, measure before changing anything.
In this example, main builds one big text and counts it two ways. The text holds 10,000 copies of a 4-word sentence. That is 250,000 bytes. A profiler would point straight at count_letters. It walks every character of the text. count_words only hops from space to space. That is the profiler's whole job — it names the function to look at first, before you change a single line.
Note
A profiler shows where time goes, not why
Read the wide boxes first, form one idea, change one thing, and measure again
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
Your release program is slow and you do not know where. What is the first move?