CodeBlanks Logo Icon CodeBlanks

Profiled optimization

Improve performance with flamegraph.

Final task: profile-guided optimization

The last task applies the right order of optimization: measure → find the bottleneck → fix the algorithm → measure again. A sample hot function: recursive Fibonacci. The flamegraph shows almost all the time is spent in fib_yavas calling itself; the number of calls grows exponentially:

fn fib_yavas(n: u32) -> u64 {
    if n < 2 { n as u64 } else { fib_yavas(n - 1) + fib_yavas(n - 2) }
}
// fib_yavas(40): ~330 million calls

No compiler setting (LTO, #[inline], target-cpu) can rescue an exponential algorithm. The gain comes from the algorithm first.

The linear version

The iterative version keeps only the last two values at each step: O(n) time, O(1) memory. Since u64 can hold at most fib(93), we report overflow safely with checked_add:

fn fib_hizli(n: u32) -> Option<u64> {
    let (mut a, mut b) = (0u64, 1u64);
    for _ in 0..n {
        let c = a.checked_add(b)?;
        a = b;
        b = c;
    }
    Some(a)
}

Then settings like lto = "thin" and codegen-units = 1 in the release profile gain the last few percent, if measurement confirms it.

Practice Fast Fibonacci

Write the fib_yavas and fib_hizli functions above. Verify with assert_eq! that the results of fib_yavas(20) and fib_hizli(20) are equal; then print the results of fib_yavas(20) and fib_hizli(90) separated by a space.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
fn fib_yavas(n: u32) -> u64 {
    if n < 2 {
        n as u64
    } else {
        fib_yavas(n - 1) + fib_yavas(n - 2)
    }
}

fn fib_hizli(n: u32) -> Option<u64> {
    let (mut a, mut b) = (0u64, 1u64);
    for _ in 0..n {
        let c = a.checked_add(b)?;
        a = b;
        b = c;
    }
    Some(a)
}

fn main() {
    assert_eq!(Some(fib_yavas(20)), fib_hizli(20));
    println!("{} {}", fib_yavas(20), fib_hizli(90).unwrap());
}

Expected output

6765 2880067194370816120

Questions and answers

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

1 Which step comes after fixing the algorithm?

  • Nothing
  • Verify the result is the same and measure again Correct answer
  • Add unsafe right away
  • Delete the profile file

Explanation: A correctness test catches a fast but wrong version; a new profile shows the next bottleneck.

2 Catch the overflow

Question
let c = a.____(b)?;
a = b;
b = c;
Answer
let c = a.checked_add(b)?;
a = b;
b = c;

Explanation: checked_add returns None on overflow; ? propagates it upward.

3 Step and tool

Term Meaning
Measure flamegraph / criterion
Bottleneck The widest plateau
Fix A better algorithm
Verify Compare with the reference

All lessons in Expert