Inlining policy for functions in std?

Lots has already been said here (and before, and before that), so no need to add too much here.

When faced with the question of whether or not to #[inline] I typically think of "what will happen if I don't do this". If it's a non-generic function, that basically means it won't get inlined across crates unless full crate graph LTO is enabled. If it's a generic function then it will already be monomorphized on use and is a candidate for inlining so long as crate-local ThinLTO is enabled (which it is by default).

So for the cases originally brought up in this thread, the consequence of not using #[inline] is they typically won't get inlined in cross-crate scenarios. Most of the time this isn't really an issue, most people aren't writing the equivalent of <[T]>::len which is practically required to be inlined.

Of course though it's also worth considering the cost of using #[inline], which is that it's a compile time cost because more code is translated elsewhere. Unfortunately one function using #[inline] has practically zero compile-time cost, but if everything is inlined then it adds up quite fast.


Unfortunately in my experience the optimal way to evaluate #[inline] is to intimately understand the compiler, codegen units, LLVM, and general compile-time cost. Naturally that's an extremely tall order and means that in practice #[inline] is both used too much and too little. Ideally the compiler would do better here, but to me at least it's not clear what could be done that wouldn't just be more expensive compiler analysis.

12 Likes