Table of Contents
Performance Overhead
Closures in Rust have zero runtime overhead in most cases due to static dispatch and compiler optimizations. However, specific scenarios can introduce costs:
Aspect | Closures | Regular Functions |
---|---|---|
Dispatch | Static (via monomorphization) | Always static (direct call) |
Memory | May store captured data (size varies) | No captured data (fixed size) |
Heap Allocation | Only if boxed (Box |
Never |
Optimization | Inlined aggressively | Inlined aggressively |
When Closures May Be Less Efficient
Heap-Allocated Trait Objects (Box)
Using dynamic dispatch (e.g., Box
- Vtable Lookups: Indirect calls via function pointers.
- Cache Misses: Fat pointers (data + vtable) reduce locality.
let closures: Vec<Box<dyn Fn(i32) -> i32>> = vec![
Box::new(|x| x + 1),
Box::new(|x| x * 2),
]; // Heap-allocated, slower to call
Large Captured Environments
Closures storing large structs (e.g., 1KB buffer) increase memory usage and may inhibit inlining:
let data = [0u8; 1024]; // 1KB array
let closure = move || data.len(); // Closure size = 1KB + overhead
Excessive Monomorphization
Generic closures with many instantiations (e.g., in a hot loop) can bloat binary size:
(0..1_000).for_each(|i| { /* Unique closure per iteration */ });
Zero-Cost Abstractions in Practice
Static Dispatch (impl Fn)
Closures are as fast as regular functions when:
- Captured data is small (e.g., primitives).
- Monomorphization doesn't cause code bloat.
let add = |x, y| x + y; // Same ASM as `fn add(x: i32, y: i32) -> i32`
Example: Inlining
fn main() {
let x = 5;
let closure = || x * 2; // Inlined → no function call
println!("{}", closure()); // ASM: `mov eax, 10`
}
Key Takeaways
✅ Use impl Fn for zero-cost static dispatch.
🚫 Avoid Box
Real-World Impact
- rayon uses closures with static dispatch for parallel iterators (no overhead).
- GUI frameworks like iced leverage closures for event handlers efficiently.
Try This: Compare the assembly output of a closure and a function with cargo rustc -- --emit asm
!
Back to Blog
Share: