标准库类型

值得阅读常见标准库类型的文档,比如BoxVecOptionResult以及Rc/Arc,以发现有时可以用来提高性能的有趣函数。

值得了解的还有高性能替代标准库类型的选择,比如MutexRwLockCondvarOnce

Box

表达式Box::default() 的效果与 Box::new(T::default()) 相同,但可能更快,因为编译器可以直接在堆上创建值,而不是在栈上构造然后复制。 示例

Vec

创建长度为 n 的零填充 Vec 的最佳方法是使用 vec![0; n]。这简单且可能比其他替代方法更快,比如使用 resizeextend 或涉及 unsafe 的任何方法,因为它可以使用操作系统的辅助。

Vec::remove 移除特定索引处的元素,并将所有后续元素向左移动一个位置,时间复杂度为 O(n)。Vec::swap_remove 用最后一个元素替换特定索引处的元素,这不保留顺序,但时间复杂度为 O(1)。

Vec::retain 高效地从 Vec 中移除多个项目。其他集合类型如 StringHashSetHashMap 也有类似的方法。

OptionResult

Option::ok_orOption 转换为 Result,如果 Option 值为 None,则传递一个 err 参数,该参数将用于错误处理。 err 会立即计算。如果其计算成本很高,应改用 Option::ok_or_else,通过闭包惰性计算错误值。例如,这样:

#![allow(unused)]
fn main() {
fn expensive() {}
let o: Option<u32> = None;
let r = o.ok_or(expensive()); // 总是评估 `expensive()`
}

应更改为:

#![allow(unused)]
fn main() {
fn expensive() {}
let o: Option<u32> = None;
let r = o.ok_or_else(|| expensive()); // 仅在需要时评估 `expensive()`
}

示例

对于 Option::map_orOption::unwrap_orResult::orResult::map_orResult::unwrap_or 也有类似的替代方法。

Rc/Arc

Rc::make_mut / Arc::make_mut 提供写时复制语义。它们使 Rc/Arc 引用可变。如果引用计数大于一,它们将 clone 内部值以确保唯一所有权;否则,它们将修改原始值。它们不经常需要,但在某些情况下可能非常有用。 示例 1示例 2

MutexRwLockCondvarOnce

parking_lot crate 提供了这些同步类型的替代实现。parking_lot 类型的 API 和语义与标准库中等价类型的相似但不相同。

以前,parking_lot 版本通常比标准库中的版本更小、更快、更灵活,但在某些平台上,标准库版本已经有了很大的改进。因此,在切换到 parking_lot 之前应该先进行测量。

如果决定普遍使用 parking_lot 类型,很容易在某些地方意外使用标准库的等价类型。您可以使用 Clippy 来避免此问题。