# 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>> {
    ...
    }
    ```