通用技巧
本书前面的章节讨论了 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 个元素,所以先处理这些情况“ 这样的注释可以很有启发性。