介绍

我完成了一个小的Rust项目(大约300行代码),它具有以下依赖关系:

  • rumqtt
  • signal
  • log
  • env_logger

  • 问题

    在不进行进一步配置的情况下使用cargo build --release时,将生成2.942.744字节(= 2,8 MiB)二进制文件。我尝试通过在Cargo.toml中启用链接时间优化(LTO)来优化此设置:
    [profile.release]
    lto = true
    

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

    如何解释呢?我在配置 cargo 时犯了任何错误?

    最佳答案

    什么是LTO?

    LTO意味着链接时间优化。通常将其设置为使用常规优化遍历,该遍历用于生成目标文件……在链接时或在链接时附加。

    为什么这有关系?

    编译器并没有针对速度超过大小或大小超过速度进行内在优化。因此,LTO也没有。

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

  • O0O1O2O3针对速度进行了优化。
  • OsOz正在优化大小。

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

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

    默认情况下,[release]配置文件指示cargo使用rustcO2调用O3,这会尝试针对大小上的速度进行优化。

    特别地,O3在很大程度上可以依赖于内联。内联是指为优化器提供更多的上下文,因此也提供了更多的优化机会... LTO提供了更多的机会来应用内联(更多已知的函数),并且这里似乎发生了更多的内联。

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

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

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

    如果使用OsOz,则大小一定会减小。

    如果使用O2O3,则删除未使用的代码,而内联会添加更多代码,因此最终结果是较大还是较小是非常不可预测的。

    那么,LTO?

    LTO为优化器提供了更好的优化机会,因此它是Releases的理想默认设置。

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

    关于rust - 为什么使用LTO会增加Rust二进制文件的大小?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52291006/

    10-11 18:34