# Aleksey Kladov - Inline in Rust (Highlights)

## Metadata
**Cover**:: https://readwise-assets.s3.amazonaws.com/static/images/article1.be68295a7e40.png
**Source**:: #from/readwise
**Zettel**:: #zettel/fleeting
**Status**:: #x
**Authors**:: [[Aleksey Kladov]]
**Full Title**:: Inline in Rust
**Category**:: #articles #readwise/articles
**Category Icon**:: 📰
**URL**:: [matklad.github.io](https://matklad.github.io//2021/07/09/inline-in-rust.html)
**Host**:: [[matklad.github.io]]
**Highlighted**:: [[2021-07-25]]
**Created**:: [[2022-09-26]]
## Highlights
- It gives the compiler the necessary context to apply further transformations.
- To achieve separate compilation, compilers expose signatures of functions, but keep function bodies invisible to other modules, preventing inlining.
- In Rust, a unit of (separate) compilation is a crate.
- it enables cross-crate inlining.
#c1
- the compiler implements this by compiling a separate copy of the #[inline] function with every crate it is used in, significantly increasing compile times.
#c2
- Besides #[inline], there are two more exceptions to this.
Generic functions are implicitly inlinable.
#c1
- The other exception is link-time optimization.
LTO opts out of separate compilation
#c2
### Inlining in Practice
- First, it’s not a good idea to apply #[inline] indiscriminately, as that makes compile time worse.
If you don’t care about compile times, a much better solution is to set lto = true in Cargo profile
https://doc.rust-lang.org/cargo/reference/profiles.html#lto
- Second, it usually isn’t necessary to apply #[inline] to private functions — within a crate, the compiler generally makes good inline decisions.
- Third, when building an application, apply #[inline] reactively when profiling shows that a particular small function is a bottleneck.
- Fourth, when building libraries, proactively add #[inline] to small non-generic functions.
Pay special attention to impls: Deref, AsRef and the like often benefit from inlining.
A library can’t anticipate all usages upfront, it makes sense to not prematurely pessimize future users.
- Fifth, mind generic functions.
It’s not too wrong to say that generic functions are implicitly inline.
As a result, they often are a cause for code bloat.
- Separate-compilation friendly private implementation.
#rust #example #code
code block
```
// Public, generic function.
// Will cause code bloat if not handled carefully!
pub fn parse_str(wat: impl AsRef<str>) -> Result<Vec<u8>> {
// Immediately delegate to a non-generic function.
_parse_str(wat.as_ref())
}
// Separate-compilation friendly private implementation.
fn _parse_str(wat: &str) -> Result<Vec<u8>> {
...
}
```