什么时候应该在 Rust 中使用 inline?

Rust 有一个“ inline”属性,可用于以下三种风格之一:

#[inline]

#[inline(always)]

#[inline(never)]

何时使用?

在 Rust 引用中,我们看到 an inline attributes section

编译器根据内部启发式自动内联函数。错误的内联函数实际上会使程序变慢,所以应该谨慎使用。

在 Rust 内部论坛中,huon 也是 关于内联指定的保守性

但是我们在 Rust 源代码中看到了 大量使用,包括标准库。在单行函数中增加了大量的内联属性,编译器可以根据参考文献通过启发式方法进行定位和优化。这些实际上是不需要的吗?

24754 次浏览

当前 Rust 编译器的一个局限性是,如果不使用 LTO (Link-Time Optimation) ,它将永远不会跨板条箱内联未标记为 #[inline]的函数。Rust 使用类似于 C + + 的单独编译模型,因为 LLVM 的 LTO 实现不能很好地扩展到大型项目。因此,暴露在其他板条箱中的小功能需要手工标记。这不是一个很好的情况,将来可能通过 LTO 和 MIR 内联的一些改进组合来解决这个问题。

#[inline(never)]有时对于调试非常有用(分离一段不能正常工作的代码)。理论上,它可以用于基准测试,但这通常是个坏主意: 关闭内联并不能阻止其他过程间优化,比如持续传播。就普通代码而言,如果您有一个经常使用的辅助函数(仅用于错误处理) ,那么它可以减少代码的大小。

#[inline(always)]通常是个坏主意; 如果一个函数足够大,以至于编译器默认情况下不会内联它,那么它就足够大,以至于调用的开销并不重要(过多的内联会增加指令缓存的压力)。也有例外,但是您需要性能度量来证明它的合理性。这个例子是那种值得考虑的情况。#[inline(always)]也可以用来提高 -O0代码的质量,但这通常不值得担心。