valff
February 11, 2019, 9:39am
1
What is the actual meaning of #[inline] attribute: does it work one level deep or does it tell the compiler to inline the whole call tree?
Consider the following code:
#[inline(always)]
fn foo(x: &mut u32) {
bar(x);
}
fn bar(x: &mut u32) {
*x += 1;
}
fn main() {
let mut x = 0;
foo(&mut x);
}
Is foo(&mut x)
supposed to be inlined as bar(&mut x)
or as x += 1
?
In other words is it a bad practice to inline delegating methods when I don't mean delegatee to be inlined.
vorner
February 11, 2019, 9:53am
2
It's one deep. And it's only a hint.
Unless you use inline(always)
or inline(never)
, the compiler will just make up its mind.
You should add such things only if you measure it actually helps ‒ inlining something might have even the very opposite effect or opposite effect on some other parts of the code.
valff
February 11, 2019, 9:59am
3
So if a function is only calling another function it is still dangerous to inline(always)
without profiling first?
valff
February 11, 2019, 10:08am
4
Or if a function is just a getter or setter - is it a bad practice to blindly inline(always)
it?
The general advice is: if you have to ask whether you should use #[inline(always)]
, you shouldn't use #[inline(always)]
. Just use #[inline]
and trust the compiler.
5 Likes
Yes.
It won't make things faster, but it'll make your debug builds slower.
Also, the compiler will inline without any attribute for generics and inside a crate, so you often don't even need the basic #[inline]
.
And if you're tempted to run around adding it to things, it's possible that what you actually want is LTO.
Edit: Haskell has some docs about this; what they say applies well to Rust too https://ghc.readthedocs.io/en/8.0.1/glasgow_exts.html#inline-pragma
valff
February 11, 2019, 7:09pm
7
Got it. Thank you all for the answers!