为什么使用LTO会增加我的Rust二进制文件的大小? 介绍
我完成了一个小的Rust项目(大约300行代码),具有以下依赖项:为什么使用LTO会增加我的Rust二进制文件的大小? 介绍,rust,compiler-optimization,lto,Rust,Compiler Optimization,Lto,我完成了一个小的Rust项目(大约300行代码),具有以下依赖项: 问题 在不进行进一步配置的情况下使用货物构建-发布时,将生成一个2.942.744字节(=2,8 MiB)的二进制文件。我试图通过在我的Cargo.toml中启用链接时间优化(LTO)来对此进行优化: [profile.release] lto = true 令我惊讶的是,二进制文件增长了,新的大小为3.848.288字节(=3,7 MiB) 这怎么解释呢?配置Cargo时是否有任何错误?可能是因为内联,内联可以增
Cargo.toml
中启用链接时间优化(LTO)来对此进行优化:
[profile.release]
lto = true
令我惊讶的是,二进制文件增长了,新的大小为3.848.288字节(=3,7 MiB)
这怎么解释呢?配置Cargo时是否有任何错误?可能是因为内联,内联可以增加代码大小以提高速度。什么是LTO? LTO意味着链路时间优化。它通常设置为使用用于生成目标文件的常规优化过程。。。而是在链接时间,或者另外 为什么这很重要? 编译器本身不会针对速度过大或大小过快进行优化;因此,LTO也不例外 相反,当调用编译器时,用户选择一个概要文件。对于
rustc
:
、O0
、O1
和O2
都在优化速度O3
和Os
正在优化大小Oz
[release]
配置文件指示cargo
使用O2
或O3
调用rustc
,这将尝试优化速度
特别是,O3
可以非常依赖于内联。内联就是为优化器提供更多的上下文,从而提供更多的优化机会。。。LTO提供了更多应用内联(更多已知函数)的机会,这里似乎出现了更多的内联
那么,为什么声称它缩小了尺寸?
它还可以缩小尺寸。可能吧
通过提供更多的上下文,优化器/链接器可以意识到部分代码或依赖项根本没有被使用,因此可以省略
如果使用Os
或Oz
,尺寸几乎肯定会下降
如果使用O2
或O3
,未使用的代码会被删除,而内联会添加更多代码,因此最终结果是大还是小都是不可预测的
那么,阿尔托?
LTO为优化器提供了更好的优化机会,因此它是一个很好的默认版本
请记住,默认情况下,
cargo
倾向于速度大于大小,如果这不适合您,您可能需要选择另一个优化方向。LTO实际上能够内联函数吗?因为这需要对特定函数进行重新编译。你能提供一些文件吗?你说的重新编译是什么意思?可以缓存外部板条箱生成的对象文件,并在每个调用站点上逐个优化每个内联函数。@EkremDinçel:我认为“重新编译”在这里意味着“代码生成”。但是,内联是LTO的一个非常重要的目的。你可能会感兴趣,为什么你希望二进制大小会下降?@MatthieuM。事实上,因为。我不知道LTO不仅优化二进制大小,而且优化性能。@PEAR:我明白了!事实上,这比那要复杂一点。