PEA*_*EAR 16 compiler-optimization rust lto
我完成了一个带有以下依赖项的小型Rust项目(大约300行代码):
在cargo build --release
没有进一步配置的情况下使用时,会生成2.942.744字节(= 2,8 MiB)的二进制数.我尝试通过启用链接时间优化(LTO)来优化这一点Cargo.toml
:
[profile.release]
lto = true
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,二进制文件增长了,新的大小为3.848.288字节(= 3,7 MiB).
怎么解释这个?我配置Cargo有什么错吗?
Mat*_* M. 24
LTO意味着链路时间优化.它通常设置为使用用于生成目标文件的常规优化通道...在链接时,或者另外.
编译器本身不会针对速度超过大小或大小来优化速度; LTO也不是.
相反,在调用编译器时,用户选择一个配置文件.用于rustc
:
O0
,O1
,O2
并O3
在优化速度.Os
并Oz
正在优化尺寸.LTO可以在任何优化级别之上进行组合,并将遵循所选的配置文件.
默认情况下,[release]
配置文件指示使用或cargo
调用,以尝试优化速度而不是大小.rustc
O2
O3
特别是,O3
可以非常依赖内联.内联就是为优化器提供更多上下文,因此有更多优化机会...... LTO提供了更多应用内联的机会(更多已知函数),并且在这里似乎发生了更多的内联.
它还减小了尺寸.有可能.
通过提供更多上下文,优化器/链接器可以意识到代码或依赖项的某些部分根本不被使用,因此可以省略.
如果使用Os
或Oz
,尺寸几乎肯定会下降.
如果在内联时使用O2
或O3
删除未使用的代码会添加更多代码,那么最终结果是更大还是更小是完全不可预测的.
LTO为优化器提供了更好的优化机会,因此它是Releases的一个很好的默认值.
请记住,cargo
默认情况下倾向于速度超过大小,如果这不适合您,您可能需要选择另一个优化方向.