CodeBlanks Logo Icon CodeBlanks

Profiling

Profile with perf and flamegraph.

Profiling

The first rule of optimization: don't guess, measure. Sampling profilers (perf on Linux, Instruments on macOS, samply everywhere) stop the program at regular intervals and record the stack trace. These samples are turned into a flamegraph: the width is the share of time spent in a function:

$ cargo install flamegraph
$ cargo flamegraph --release -- girdi.txt

# Cargo.toml: symbol info in the profile
[profile.release]
debug = true

In a flamegraph, the widest "plateaus" (wide boxes with no calls above them) are the first places to optimize.

Folded stacks

Flamegraph tools process samples in a "folded" form: each line is a call chain separated by semicolons. Counting how many samples the same leaf function appears in gives where the time goes:

main;hesapla;topla
main;hesapla;topla
main;yaz

// leaf count: topla 2, yaz 1 → 2/3 of the time in topla

The inferno crate produces an SVG flamegraph from this format.

Practice Count the samples

In the samples ["main;hesapla;topla", "main;hesapla;topla", "main;yaz"], find the leaf functions with rsplit(';') and count them in a BTreeMap. Print each as name count on separate lines.

Starter code

main.rs
use std::collections::BTreeMap;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::collections::BTreeMap;

fn main() {
    let yiginlar = ["main;hesapla;topla", "main;hesapla;topla", "main;yaz"];
    let mut sayim: BTreeMap<&str, u32> = BTreeMap::new();
    for o in yiginlar {
        let yaprak = o.rsplit(';').next().unwrap();
        *sayim.entry(yaprak).or_insert(0) += 1;
    }
    for (ad, n) in &sayim {
        println!("{} {}", ad, n);
    }
}

Expected output

topla 2
yaz 1

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why must the profile be taken on a release build?

  • Debug can't be profiled
  • Convention
  • It isn't needed
  • Bottlenecks in a debug build are completely different; unoptimized abstractions give misleading results Correct answer

Explanation: debug = true adds symbols to the release build; optimization is kept and function names are visible.

2 Take the leaf

Question
let yaprak = yigin.____(';').next().unwrap();
Answer
let yaprak = yigin.rsplit(';').next().unwrap();

Explanation: rsplit splits from the right; the first piece is the chain's last function.

3 Tool and role

Term Meaning
perf / samply Sampling profiler
cargo flamegraph Produces a flame graph
debug = true Symbols in release
criterion Micro benchmark

All lessons in Expert