14.4 Performance Considerations

A common question is whether Option<T> adds overhead compared to raw pointers and sentinel values. Rust’s optimizations often make this impact negligible.

14.4.1 Memory Representation (Null-Pointer Optimization)

Rust employs the null-pointer optimization (NPO) where possible:

  • If T itself has some form of invalid bit pattern (as with references or certain integer types), then Option<T> can usually occupy the same space as T.
  • If T can represent all possible bit patterns, then Option<T> usually needs an extra byte for a ‘discriminant’ that tracks which variant is active.
use std::mem::size_of;

fn main() {
    // Often the following holds true:
    assert_eq!(size_of::<Option<&i32>>(), size_of::<&i32>());
    println!("Option<&i32> often has the same size as &i32> due to NPO.");
}

14.4.2 Computational Overhead

At runtime, handling Option<T> typically boils down to a check for Some or None. Modern CPUs handle such conditional checks efficiently, and the compiler can optimize many of them away in practice.

14.4.3 Source-Code Verbosity

Compared to simply returning NULL in C, you might feel that Rust demands more steps to handle Option<T>. However, this explicitness is what prevents entire categories of bugs, improving overall code reliability.