为什么使用LTO会增加Rust二进制文件的大小?

问题描述 投票:14回答:2

介绍

我完成了一个带有以下依赖项的小型Rust项目(大约300行代码):

问题

在没有进一步配置的情况下使用cargo build --release时,会生成2.942.744字节(= 2,8 MiB)的二进制数。我尝试通过在Cargo.toml中启用链接时间优化(LTO)来优化它:

[profile.release]
lto = true

令我惊讶的是,二进制文件增长了,新的大小为3.848.288字节(= 3,7 MiB)。

怎么解释这个?我配置Cargo有什么错吗?

rust compiler-optimization lto
2个回答
19
投票

什么是LTO?

LTO意味着链路时间优化。它通常设置为使用用于生成目标文件的常规优化通道...在链接时,或者另外。

为什么这有关系?

编译器本身不会针对速度超过大小或大小来优化速度; LTO也不是。

相反,在调用编译器时,用户选择一个配置文件。对于rustc

  • O0O1O2O3正在优化速度。
  • OsOz正在优化尺寸。

LTO可以在任何优化级别之上进行组合,并将遵循所选的配置文件。

那么为什么尺寸会增加呢?

默认情况下,[release]配置文件指示cargo使用rustcO2调用O3,它试图优化速度而不是大小。

特别是,O3可以非常依赖内联。内联就是为优化器提供更多上下文,因此有更多优化机会...... LTO提供了更多应用内联的机会(更多已知函数),并且在这里似乎发生了更多的内联。

那么为什么this blog post声称它减小了尺寸?

它还减小了尺寸。有可能。

通过提供更多上下文,优化器/链接器可以意识到代码或依赖项的某些部分根本不被使用,因此可以省略。

如果使用OsOz,大小几乎肯定会下降。

如果使用O2O3,删除未使用的代码,同时内联添加更多代码,因此最终结果是更大还是更小是无法预测的。

我知道,LTO?

LTO为优化器提供了更好的优化机会,因此它是Releases的一个很好的默认值。

请记住,默认情况下,cargo倾向于速度超过大小,如果这不适合您,您可能想要选择另一个优化方向。


5
投票

可能是因为内联,可以增加代码大小以提高速度。

© www.soinside.com 2019 - 2024. All rights reserved.