# When should I use #\[inline\]?

**URL:** <https://internals.rust-lang.org/t/when-should-i-use-inline/598>\
**Category:** guidelines\
**Created:** [October 4, 2014, 7:57pm UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598 "2014-10-04T19:57:18Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![SimonSapin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/simonsapin/32/3158_2.png) [@SimonSapin](https://internals.rust-lang.org/u/SimonSapin)\
**Post date:** [October 4, 2014, 7:57pm UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/1 "2014-10-04T19:57:18Z")

</div>

[Inline attributes](http://doc.rust-lang.org/reference.html#inline-attributes) can be added to functions and methods. As a library author, when should I use them?

I feel like the compile probably knows better than me when inlining is beneficial or not, so I don’t use `#[inline(always)]` or `#[inline(never)]`. (I guess I only would if measured evidence shows that it helps significantly when trying to optimize something.) But `#[inline]` is less clear-cut. There can be no cross-crate inlining without it, and cross-crate is the main usage of a library. So I tend to add it to functions that I feel are “small enough”, but that’s kinda random.

Is any use of `#[inline]` without benchmarks premature optimization? Or should I `#[inline]` _all the things_ and let the compiler figure it out? Or is there a better criteria for something in between?

---

<div class="post-metadata">

**Author:** ![Jurily](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jurily/32/212_2.png) [@Jurily](https://internals.rust-lang.org/u/Jurily)\
**Post date:** [October 5, 2014, 6:06am UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/2 "2014-10-05T06:06:17Z")

</div>

Without knowing anything about the compiler internals, I’d lean on using it everywhere unless binary size or compile time is a concern.

I feel like rustc should allow cross-crate inlining by default, with maybe an `#[inline(seldom)]` anti-hint and a bunch of command line options.

---

<div class="post-metadata">

**Author:** ![huon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/huon/32/3698_2.png) [@huon](https://internals.rust-lang.org/u/huon)\
**Post date:** [October 5, 2014, 6:31am UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/3 "2014-10-05T06:31:15Z")

</div>

`#[inline]` has non-trivial compilation time costs (a function with `#[inline]` is recompiled in every crate that uses it, like a generic function), and, more importantly, it can easily be a pessimisation, as it is giving an inline-hint to override LLVM’s better judgement by increasing the cost threshold under which the function will be inlined.

If you really want the fastest binary the compiler can make, you can/should use link-time optimisation (`rustc -C lto`) which has access to all of the crate’s Rust dependencies, in inlinable form (including things without `#[inline]` attributes). This is very slow to compile, but it’s isomorphic to adding `#[inline]` to everything and I’d guess that the attributes on everything is even slower than `-C lto`.

`#[inline]` should be preferred to be used only on performance-critical things; e.g. putting `#[inline]` on most functions doing IO will be absolutely pointless for run-time performance (and just drag compile-time performance down the drain).

---

<div class="post-metadata">

**Author:** ![SimonSapin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/simonsapin/32/3158_2.png) [@SimonSapin](https://internals.rust-lang.org/u/SimonSapin)\
**Post date:** [October 5, 2014, 9:03am UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/4 "2014-10-05T09:03:25Z")

</div>

> [@huon](#):
>
> If you really want the fastest binary the compiler can make [...]

What if I’m making a library for other people to use, and I don’t know what they really want?

---

<div class="post-metadata">

**Author:** ![SimonSapin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/simonsapin/32/3158_2.png) [@SimonSapin](https://internals.rust-lang.org/u/SimonSapin)\
**Post date:** [October 5, 2014, 9:09am UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/5 "2014-10-05T09:09:15Z")

</div>

From the reference:

> `#[inline]` and `#[inline(always)]` always causes the function to be serialized into crate metadata to allow cross-crate inlining.

This is ambiguous on what happens if you _don’t_ specify `#[inline]`. _Can_ the compiler still decide to serialize the function into crate metadata, e.g. if it’s small enough? If so, should the guideline be “don’t use any inline attribute and let the compiler do its job”?

---

<div class="post-metadata">

**Author:** ![huon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/huon/32/3698_2.png) [@huon](https://internals.rust-lang.org/u/huon)\
**Post date:** [October 5, 2014, 10:19am UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/6 "2014-10-05T10:19:55Z")

</div>

> [@SimonSapin](#):
>
> What if I’m making a library for other people to use, and I don’t know what they really want?

Link-time optimisation is something that application authors opt-in to, it requires no effort on the part of library authors. It was unclear of me to say "you" in that context. Rephrased: to get the fastest binary available, an application author can use LTO and that will suck in (and possibly inline) functions from all the Rust libraries that they depend on, whether or not there is `#[inline]` or `#[inline(always)]` annotations in those libraries. That is, `-C lto` is a little like a retroactive `#[inline]` on steroids.

(In fact, AIUI, library authors _cannot_ do anything with `-C lto`: it only works when producing a final artifact, that is, a binary or static-lib.)

> [@SimonSapin](#):
>
> Can the compiler still decide to serialize the function into crate metadata, e.g. if it’s small enough? If so, should the guideline be “don’t use any inline attribute and let the compiler do its job”?

The compiler currently does not automatically serialize to metadata (that is, only generic, `#[inline]` and `#[inline(always)]` functions are in metadata)... but, as you say, it's not explicitly disallowed.

---

<div class="post-metadata">

**Author:** ![Gankra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gankra/32/6002_2.png) [@Gankra](https://internals.rust-lang.org/u/Gankra)\
**Post date:** [October 5, 2014, 9:16pm UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/7 "2014-10-05T21:16:42Z")

</div>

In a PR I just posted, @strcat notes about generic code:

> Since it's all generic code, inlining across crates is already possible. That may change in the future if Rust ever supports re-exporting instantiations of generics like C++11.

---

<div class="post-metadata">

**Author:** ![NeoLegends](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/neolegends/32/1805_2.png) [@NeoLegends](https://internals.rust-lang.org/u/NeoLegends)\
**Post date:** [March 24, 2017, 4:13pm UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/8 "2017-03-24T16:13:08Z")

</div>

Is there an update to this? After all, this topic is over two years old.

---

<div class="post-metadata">

**Author:** ![steveklabnik](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steveklabnik/32/4524_2.png) [@steveklabnik](https://internals.rust-lang.org/u/steveklabnik)\
**Post date:** [March 24, 2017, 5:35pm UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/9 "2017-03-24T17:35:00Z")

</div>

Nothing has really changed in two years.

---

<div class="post-metadata">

**Author:** ![SimonSapin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/simonsapin/32/3158_2.png) [@SimonSapin](https://internals.rust-lang.org/u/SimonSapin)\
**Post date:** [June 21, 2017, 11:41am UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/10 "2017-06-21T11:41:42Z")

</div>

[https://bugzilla.mozilla.org/show\_bug.cgi?id=1351737](https://bugzilla.mozilla.org/show_bug.cgi?id=1351737) is about the generated code size in Stylo. A single symbol is 544 KB. In related files, hundreds of functions and methods have `#[inline]` added to them, probably out of habit.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:22am UTC](https://internals.rust-lang.org/t/when-should-i-use-inline/598/11 "2019-03-25T08:22:57Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
