Rust有一个"内联"属性,可用于以下三种口味之一:

#[inline]

#[inline(always)]

#[inline(never)]

什么时候使用?

在Rust参考资料中,我们看到an inline attributes section个说法

编译器根据内部启发法自动内联函数.不正确的内联函数实际上会使程序变慢,因此使用时应小心.

在Rust internals论坛上,huon也获得了conservative about specifying inline分.

但我们在Rust source中看到了considerable usage个,包括标准库.许多内联属性被添加到单行函数中,这应该很容易让编译器根据参考通过启发式发现和优化.这些事实上是不需要的吗?

推荐答案

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

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

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

Rust相关问答推荐

如何从Rust记录WASM堆内存使用情况?

Rust中的相互递归特性与默认实现

当rust中不存在文件或目录时,std::FS::File::Create().unwire()会抛出错误

如何提高自定义迭代器的`extend`性能

在Rust中,如果Result是Err,运行副作用(如日志(log)记录)的惯用方法是什么

默认特征实现中的生命周期问题

使用铁 rust S还原对多个数组执行顺序kronecker积

如何使用RefCell::JOYMOMTborrow 对 struct 不同字段的可变引用

循环访问枚举中的不同集合

如何设置activx websocket actorless的消息大小限制?

为什么 GAT、生命周期和异步的这种组合需要 `T: 'static`?

如何返回 struct 体中向量的切片

从字节数组转换为字节元组和字节数组时,为什么 Transmute 会对字节重新排序?

为什么 Rust 的临时值有时有参考性有时没有?

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

Rust 异步和 AsRef 未被发送

为什么我可以同时传递可变和不可变引用?

从 Cranelift 发出 ASM

为什么这个 Trait 无效?以及改用什么签名?

如何在宏中的多个参数上编写嵌套循环?