17 通用技巧
2 分钟阅读
译文 · 基于 The Rust Performance Book
通用技巧
原文链接: https://nnethercote.github.io/perf-book/general-tips.html
本书前面各节讨论了 Rust 特有的技巧。本节简要概述一些通用的性能原则。
只要避免明显陷阱(例如使用非 release 构建),Rust 代码通常既快又省内存,尤其若你习惯 Python、Ruby 等动态类型语言,或 Java、C# 等带垃圾回收的静态类型语言。
优化后的代码往往更复杂,编写也比未优化代码更费力。因此,只值得优化热点代码。
最大的性能提升往往来自算法或数据结构的改动,而非底层微优化。 示例 1, 示例 2。
编写能良好利用现代硬件的代码并不总是容易,但值得努力。例如,尽可能减少缓存未命中和分支预测失败。
多数优化只带来小幅加速。虽然单次小幅加速不易察觉,但若做得足够多,累积效果会很明显。
不同性能分析器各有长处,使用多种工具是好的做法。
当性能分析表明某函数是热点时,有两种常见加速方式:(a) 让该函数更快,和/或 (b) 减少调用次数。
消除愚蠢的拖慢往往比引入巧妙的加速更容易。
避免不必要的计算。惰性/按需计算常常是赢家。 示例 1, 示例 2。
复杂的一般情况往往可以通过乐观地检查更简单、更常见的特殊情况来避免。 示例 1, 示例 2, 示例 3。 尤其当小尺寸占主导时,专门处理 0、1 或 2 个元素的集合往往是赢家。 示例 1, 示例 2, 示例 3, 示例 4。
类似地,处理重复数据时,常可用简单的数据压缩:为常见值使用紧凑表示,对异常值回退到辅助表。 示例 1, 示例 2, 示例 3。
当代码处理多种情况时,测量各情况频率并优先处理最常见的情况。
处理具有高局部性的查找时,在数据结构前加一个小缓存可能有效。
优化后的代码往往结构不直观,因此说明性注释很有价值,尤其是引用性能分析测量结果的注释。像「该向量 99% 的时间只有 0 或 1 个元素,因此先处理这些情况」这样的注释很有启发性。