103

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

#[inline]

#[inline(always)]

#[inline(never)]

什么时候应该使用它们?

在 Rust 参考中,我们看到一个内联属性部分

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

在 Rust 内部论坛中,huon对于指定 inline 也很保守

但是我们在 Rust 源代码中看到了相当多的使用,包括标准库。在单行函数中添加了很多内联属性,编译器应该很容易根据参考通过启发式发现和优化。这些实际上不需要吗?

4

1 回答 1

81

当前 Rust 编译器的一个限制是,如果您不使用 LTO(链接时间优化),它永远不会内联未#[inline]跨 crate 标记的函数。Rust 使用类似于 C++ 的单独编译模型,因为 LLVM 的 LTO 实现不能很好地扩展到大型项目。因此,暴露给其他 crate 的小功能需要手工标记。这不是一个很好的情况,它很可能在未来通过对 LTO 和 MIR 内联的一些改进组合来解决。

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

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

于 2016-06-05T08:26:55.463 回答