In this lesson, you will learn how to optimize your Rust code by allowing the compiler to see through crate boundaries using Inlining and Link-Time Optimization (LTO).
The "Crate Wall" Problem
Normally, when you write a Rust program, the compiler processes your code one crate at a time. When you call a function defined in an external dependency, the compiler treats that function as a "black box." It knows the function signature, but it cannot see the actual implementation inside the other crate to decide if it should be inlined.
Inlining Across Boundaries
Inlining is the process where the compiler replaces a function call with the actual body of the function, removing the overhead of jumping to a different memory address. While the compiler handles this easily within a single file, it struggles across crates.
To suggest that the compiler should inline a function across crate boundaries, you use the #[inline] attribute:
// In your library crate
#[inline]
pub fn calculate_sum(a: i32, b: i32) -> i32 {
a + b
}
By adding #[inline], you signal to the compiler that it is beneficial to copy this logic directly into the code of any crate that uses it, potentially leading to faster execution.
Link-Time Optimization (LTO)
Even with #[inline], there are limits to what the compiler can do during standard compilation. This is where Link-Time Optimization (LTO) comes in.
LTO is a technique where the compiler performs optimizations at the very end of the build process—when all crates are combined into a final binary. By enabling LTO, the compiler gains a "global view" of your entire application. It can identify functions that were not explicitly marked for inlining, prune unused code more aggressively, and make better decisions about how to layout your program for the CPU.
You enable LTO in your Cargo.toml file:
[profile.release]
lto = true
Setting lto = true tells Rust to look across every crate in your project to find performance gains that were invisible during the initial compilation phase. While this makes your final build process slower, it often results in a significantly faster and smaller executable.
Key Takeaway: Use #[inline] to suggest optimizations for specific functions and enable LTO in your release profile to allow the compiler to optimize your entire application as one unified unit.