OSORIO.SYS

Zero-Cost Abstractions: Myth or Reality?

“Zero-cost” does not mean free. It means you do not pay for what you do not use, and what you do use should compile down to the code you would have written by hand.

That claim is true often enough to be useful, and false often enough to be dangerous if you never look at the assembly.

Where it holds

A tight iterator chain over a slice usually collapses to the same loop as a for i in 0..n in --release. Generics monomorphize. Option<&T> is a nullable pointer. Those are the examples that made the slogan famous.

rust
pub fn sum_even(xs: &[u32]) -> u32 {
    xs.iter().copied().filter(|x| x % 2 == 0).sum()
}

On a current LLVM, that is a vectorizable loop. The adapters are a compile-time story, not a runtime one.

Where it leaks

The cost shows up when the abstraction hides:

  • Indirect calls (dyn Trait) that the compiler cannot devirtualize
  • Extra copies because a type is not Copy and you .clone() to satisfy a bound
  • Debug formatting, logging, or panic paths that survive into the hot function

Zero-cost is a property of a specific compilation, not of the language in the abstract.

How to check

Keep a cargo asm or Compiler Explorer tab next to the function you care about. If the iterator version and the hand-written version diverge, the slogan just told you where to look.