我完成了一个小的Rust项目(大约300行代码),该项目具有以下依赖性:
在不进行进一步配置的情况下使用cargo build --release
时,将生成2.942.744字节(= 2,8 MiB)二进制文件。我试图通过在Cargo.toml
中启用链接时间优化(LTO)来对此进行优化:
[profile.release]
lto = true
令我惊讶的是,二进制文件不断增长,其新大小为3.848.288字节(= 3,7 MiB)。
这怎么解释?我在配置货运时犯了什么错误?
答案 0 :(得分:19)
LTO表示链接时间优化。通常将其设置为使用常规的优化过程来生成目标文件,而不是在链接时使用。
编译器并没有针对速度超过大小或大小超过速度进行内在优化。因此LTO也没有。
相反,在调用编译器时,用户将选择一个配置文件。对于rustc
:
O0
,O1
,O2
和O3
正在优化速度。Os
和Oz
正在优化尺寸。LTO可以组合在任何优化级别之上,并且将遵循所选的配置文件。
默认情况下,[release]
配置文件指示cargo
用rustc
或O2
调用O3
,尝试进行优化速度超过尺寸。
尤其是O3
可以非常依赖内联。内联就是要为优化器提供更多的上下文,从而提供更多的优化机会... LTO提供了更多的机会来应用内联(更多已知的函数),并且这里似乎发生了更多的内联。
它也减小了尺寸。可能。
通过提供更多的上下文,优化器/链接器可以意识到部分代码或依赖项根本没有使用,因此可以省略。
如果使用Os
或Oz
,则尺寸肯定会减小。
如果使用O2
或O3
,则删除未使用的代码,而内联会添加更多代码,因此最终结果是较大还是较小是完全不可预测的。
LTO为优化器提供了更好的优化机会,因此它是Releases的很好默认值。
请记住,默认情况下,cargo
倾向于速度超过尺寸,如果这不适合您,则可能需要选择另一个优化方向。
答案 1 :(得分:5)
可能是因为内联,它可以增加代码大小以提高速度。