如何加快rust构建时间

572次阅读  |  发布于1年以前

对于使用Rust编程语言的人来说,构建时间有时是非常痛苦的,对于基于LLVM的语言来说,缓慢的编译时间并不是什么新鲜事,但考虑到Rust的全面编译检查,时间消耗可能会迅速增长。

在这篇文章中,我们将探讨如何减少rust的构建时间。改进rust构建时间的方法有4种。

设置配置文件

1,Release flag -- 发布版本比开发版本更优化。如果你做一个简单的cargo build,可能会看到类似这样的东西。

Finished dev [unoptimized + debuginfo] target(s) in 54.20s

发布版本要快得多,因为它通常省略了一些检查,比如调试断言和整数溢出检查。要创建一个发布版本,请使用cargo build --release 或 cargo run --release,将看到这样的输出:

Finished release [optimized] target(s) in 15.04s

2,Opt-level -- 可以通过在构建命令或Cargo.toml中设置此标志来指定所需的优化级别。优化级别包括:

要使用它,请执行以下操作:

$ RUSTFLAGS="-C opt-level=2" cargo build --release

或者通过在Cargo.toml的配置文件设置它的级别:

[profile.release]
opt-level = 'z' # Optimize for size

循环向量化 - 是一个使用SIMD减少汇编指令的过程,以选择一组可以并行化为多个数据点(通常是数组)的指令。有些指令不能自动向量化,甚至可能最终使代码变慢,因此选择关闭循环向量化。

3,链接时间优化 -- 对于大多数基于LLVM的语言,单个模块是相互独立优化的,通过启用LTO,编译器可以利用模块间的依赖来进一步优化它们。要使用它,可以在构建时传递-c lto=true,或者在Cargo.toml的配置文件中使用它。

要使用它,请执行以下操作:

$ RUSTFLAGS="-C lto=true" cargo build

或者通过在cargo.toml的配置文件级别设置它:

[profile.release]
lto = true

CPU专用指令

如果不太关心二进制文件在不同处理器上的兼容性,可以告诉编译器生成特定于某个CPU体系结构的最新(也可能是最快的)指令。

要做到这一点,你可以使用这个标志-C target-cpu=native,它将使用当前CPU的最佳指令:

$ RUSTFLAGS="-C target-cpu=native" cargo build --release

这可能会产生很大的优化,特别是如果编译器在代码中发现向量化。

如果你不确定-C target-cpu=native是否在最佳状态下工作,可以使用命令rustc --print cfg和rustc --print cfg -C target-cpu=native来比较输出,看看在后一种情况下是否正确检测到CPU的特性。

建立缓存

Mozilla创建了自己的ccache版本,称为Sccache,这是一个编译器缓存工具,通过缓存以前的编译结果并检测何时再次进行相同的缓存来减少重新编译的时间。与高速缓存相比,它的优点是可以利用云平台来存储重新编译缓存。

可以使用使用以下命令安装:

cargo insatll sccache --locked

请记住还有其他更好的方法来安装它,因为从源代码编译通常是资源密集型的,不建议在CI管道中使用这种方法。

LLVM IR

Rust编译器使用LLVM作为其后端。LLVM的执行可能占编译时间的很大一部分,特别是当Rust编译器的前端生成大量IR时,这需要LLVM花很长时间来优化。

像cargo-llvm-lines这样的工具可以用来查看哪些函数会生成最多的LLVM IR。泛型函数通常是最需要优化的函数。如果泛型函数导致IR膨胀,有以下几种方法可以修复它:

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8