Summary - Zero-cost abstraction
- Rust course
- Expert
- Lesson 18/46
- 5 min
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
fn main() {
// buraya yaz
}Sample solution
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>&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
fn uygula_dyn(f: &____ Fn(i32) -> i32, n: i32) -> i32 {
f(n)
}
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 |