高性能防锈的廉价诀窍

2020-06-23 12:01:09

那么,您正在编写Rust,但是它还不够快?即使您使用的是Cargo Build--Release?以下是一些可以提高Rust项目运行时速度的小事情--实际上不需要更改任何代码!

请记住,以下建议并不能取代实际的性能分析和优化!我也认为不用说,检测其中是否有任何帮助的唯一方法是拥有代表您的应用程序在实际使用中的行为的基准测试。

首先,让我们在进行货物构建-发布时启用一些更多的优化。交易非常简单:我们启用了一些使构建发布构建变得更慢的功能,但作为奖励,我们可以获得更彻底的优化。

我们将下面介绍的标志添加到主Cargo.toml文件中,即最顶层的清单文件,以防您使用货物工作区。如果您还没有名为profile.release的节,请添加它:

我们要做的第一件事是启用链接时间优化(LTO),这是一种全程序或模块间优化,因为它在将二进制文件的不同部分链接在一起时作为最后一步运行。您可以认为它允许更好地跨依赖边界进行内联(但它当然要比这复杂得多)。

Ruust可以使用多种链接器风格,我们想要的是“跨所有板条箱优化”,也就是“胖”。要设置这一点,请在您的个人资料中添加LTO标志:

接下来是一个类似的主题。为了加快编译速度,Rust尝试将板条箱拆分成小块,并尽可能并行编译尽可能多的块。缺点是编译器在这些块中优化代码的机会较少。因此,让我们告诉它在每个板条箱中执行一个块:

默认情况下,Rust希望构建一个可以在目标体系结构的尽可能多的机器上运行的二进制文件。但是,您可能实际上有一个非常新的CPU,具有很酷的新功能!

作为“铁锈标志”,即环境变量RUSTFLAGS或目标的铁锈标志字段。

现在我们进入一些更不安全的选项。还记得Rust在默认情况下如何使用堆栈展开(在最常见的平台上)吗?这会以性能为代价!让我们跳过堆栈跟踪和捕获异常的能力,以减少代码大小和更好地使用高速缓存:

请注意,一些库可能依赖于展开,如果您启用此功能,将会发生可怕的爆炸!

许多Rust程序做的一件事就是分配内存。他们不仅自己做这件事,而且实际上使用一个(外部)库来做这件事:分配器。当前的Rust二进制程序默认使用默认的系统分配器,以前它们自己的分配器包含在标准库中。(这种变化导致了更小的二进制文件和更好的可调试性,这让一些人相当高兴)。

不过,有时您系统的分配器不是最佳选择。别担心,我们可以更改它!我建议同时尝试jemalloc和mimalloc。

jemalloc是Rust以前附带的分配器,Rust编译器至今仍在使用它自己。它的重点是减少内存碎片并支持高并发。它也是FreeBSD上的默认分配器。如果您对此感兴趣,让我们试一试!

另一个有趣的替代分配器是mimalloc.它是由微软开发的,占用的空间相当小,并且在自由列表方面有一些创新的想法。

它还具有可配置的安全功能(请查看其Cargo.toml)。这意味着我们可以关闭它们以获得更高的性能!将mimalloc板条箱添加为依赖项,如下所示:

这是LLVM的一个很好的功能,但是我从来没有用过。请看一下文档。

现在,您需要实际调整代码并修复所有的clone()调用。不幸的是,这是另一个帖子的主题!(在您等待我再写一年的时候,您可以阅读有关奶牛的内容!)。

编辑:人们不断询问关于如何优化Rust代码的实际提示。幸运的是,我骗到了他们,他们有一些很好的材料供我链接: