When should inline be used in Rust?
Rust具有" inline "属性,可以在以下三种口味之一中使用:
#[inline]
#[inline(always)]
#[inline(never)]
何时应使用它们?
在Rust参考中,我们看到一个内联属性部分,内容为
The compiler automatically inlines functions based on internal heuristics. Incorrectly inlining functions can actually make the program slower, so it should be used with care.
在Rust内部知识论坛中,huon在指定内联方面也很保守。
但是我们在Rust源中看到了很多用法,包括标准库。许多内联属性被添加到单行函数中,这对于编译器来说很容易根据参考资料通过启发式方法进行发现和优化。实际上不需要这些吗?
当前Rust编译器的一个限制是,如果您不使用LTO(链接时间优化),它将永远不会在没有package的情况下内联未标记为#[inline]的函数。 Rust使用类似于C的单独编译模型,因为LLVM的LTO实现不能很好地扩展到大型项目。因此,需要手工标记暴露在其他package箱中的小功能。这不是一个好情况,将来可能会通过对LTO和MIR内联进行一些改进来解决。
#[inline(never)]有时对于调试很有用(分隔一段无法按预期运行的代码)。从理论上讲,它可以用于基准测试,但这通常是个坏主意:关闭内联并不能阻止其他过程间优化,例如恒定传播。就普通代码而言,如果您有一个仅用于错误处理的常用辅助函数,它可以减少代码大小。
#[inline(always)]通常是个坏主意;如果一个函数足够大,以至于编译器默认不会内联该函数,则它足够大,以至于调用的开销无关紧要(过多的内联会增加指令高速缓存的压力)。有例外,但是您需要进行性能评估以证明其合理性。此示例是一种值得考虑的情况。 #[inline(always)]也可以用来提高-O0的代码质量,但这通常不必担心。
- 请注意,在紧急情况内在函数上使用inline(never),以确保优化程序不会内联仅在紧急情况下调用的函数。
-
-1,因为第一点还缺少一些东西。泛型项目可以跨package箱内联,因为它们在实例化时可以有效地进行编译,因此内联所需的代码很容易获得。这意味着大量未标记的此类项目仍可以跨箱内联。在某些基本的库箱中,每个项目都是通用的!