Course contentsShow
← Rust
Lesson 802 of 1,9106. Generics and Static DispatchFree lesson

Strategic Use of Inlining Attributes

Apply the inline attribute in generic methods to balance code size against runtime speed.

In this lesson, you will learn how to strategically apply the #[inline] attribute to generic methods to manage the trade-off between execution speed and binary size.

The Cost of Generics

When you write a generic function in Rust, the compiler performs monomorphization. It generates a unique version of your function for every concrete type used. While this allows for high-performance static dispatch, it can lead to "code bloat" if the compiler decides not to inline these functions. Conversely, if you have a tiny generic function used in many places, the overhead of the function call itself might outweigh the execution time of the logic inside.

Strategic Inlining

By default, the Rust compiler is excellent at deciding what to inline. However, when working with generics across module or crate boundaries, the compiler’s visibility is limited. Using #[inline] serves as a hint that you want the function’s body copied directly into the caller's scope.

Consider this example:

pub struct Calculator;

impl Calculator {
    // We hint to the compiler to inline this generic method
    // to remove the function call overhead for simple operations.
    #[inline]
    pub fn process<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
        a + b
    }
}

When to Use It

  • Small Generic Helpers: If a generic method is just a few lines of code (like a simple wrapper or a trait-based getter), #[inline] can significantly reduce call overhead.
  • Cross-Crate Boundary: If your generic code is in a library, #[inline] allows the compiler to optimize the implementation within the downstream crate rather than forcing a jump to your library's pre-compiled instance.
  • Avoiding Bloat: Be careful! Marking a large or recursive generic function with #[inline] forces the compiler to duplicate that large amount of code everywhere it is called, which can lead to massive binary sizes and cache misses.

Think of #[inline] as a precision tool: use it for small, performance-critical generic wrappers to help the optimizer see through your abstractions, but avoid using it on large functions where the cost of code duplication outweighs the speed gain.

Key Takeaway: Use #[inline] on small, frequently called generic methods to eliminate call overhead, but avoid applying it to large functions to keep your binary size and instruction cache usage efficient.