CodeBlanks Logo Icon CodeBlanks

Summary - Zero-cost abstraction

Combine monomorphization, fusion and inline to write a performance comparison.

Zero-cost summary

Iterators, closures and generics turn into hand-written code in a release build. Monomorphization is fast but bloats code; the inner-function pattern or dyn reduces it. Adapter chains fuse into a single loop; a needless collect in the middle breaks this. #[inline] and #[cold] are hints. Bounds checks disappear with iterators, zip and a hoisted assert. Every claim should be measured: criterion, godbolt, a profile.

Two calling styles

The same closure can be passed in two ways:

fn uygula_generic<F: Fn(i32) -> i32>(f: F, n: i32) -> i32 {
    f(n)     // F is compiled separately for each closure, inlined
}

fn uygula_dyn(f: &dyn Fn(i32) -> i32, n: i32) -> i32 {
    f(n)     // a single copy, called through the vtable
}

Practice Two calls

Write the uygula_generic and uygula_dyn functions above. Pass the closure |x| x + 1 with 41 to both and print the results separated by a space.

Starter code

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

Sample solution

main.rs
fn uygula_generic<F: Fn(i32) -> i32>(f: F, n: i32) -> i32 {
    f(n)
}

fn uygula_dyn(f: &dyn Fn(i32) -> i32, n: i32) -> i32 {
    f(n)
}

fn main() {
    let artir = |x| x + 1;
    println!("{} {}", uygula_generic(artir, 41), uygula_dyn(&artir, 41));
}

Expected output

42 42

Questions and answers

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

1 What is the main difference between a generic closure parameter and <code>&amp;dyn Fn</code>?

  • No difference
  • dyn is faster
  • Generic allocates on the heap
  • Generic is inlined; dyn is a vtable call but a single copy is compiled Correct answer

Explanation: Generic in a hot loop, dyn for rarely called callbacks is usually a good choice.

2 Dynamic closure

Question
fn uygula_dyn(f: &____ Fn(i32) -> i32, n: i32) -> i32 {
    f(n)
}
Answer
fn uygula_dyn(f: &dyn Fn(i32) -> i32, n: i32) -> i32 {
    f(n)
}

Explanation: &dyn Fn works with a single compiled copy.

3 Group summary

Term Meaning
Yineleyici Same code as a loop
Monomorfizasyon Code bloat
#[cold] Rare path
zip Check-free pairing

All lessons in Expert