标准库类型
值得阅读常见标准库类型的文档,比如Box
、Vec
、Option
、Result
以及Rc
/Arc
,以发现有时可以用来提高性能的有趣函数。
值得了解的还有高性能替代标准库类型的选择,比如Mutex
、RwLock
、Condvar
和Once
。
Box
表达式Box::default()
的效果与 Box::new(T::default())
相同,但可能更快,因为编译器可以直接在堆上创建值,而不是在栈上构造然后复制。
示例。
Vec
创建长度为 n
的零填充 Vec
的最佳方法是使用 vec![0; n]
。这简单且可能比其他替代方法更快,比如使用 resize
、extend
或涉及 unsafe
的任何方法,因为它可以使用操作系统的辅助。
Vec::remove
移除特定索引处的元素,并将所有后续元素向左移动一个位置,时间复杂度为 O(n)。Vec::swap_remove
用最后一个元素替换特定索引处的元素,这不保留顺序,但时间复杂度为 O(1)。
Vec::retain
高效地从 Vec
中移除多个项目。其他集合类型如 String
、HashSet
和 HashMap
也有类似的方法。
Option
和 Result
Option::ok_or
将 Option
转换为 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_or
、Option::unwrap_or
、Result::or
、Result::map_or
和 Result::unwrap_or
也有类似的替代方法。
Rc
/Arc
Rc::make_mut
/ Arc::make_mut
提供写时复制语义。它们使 Rc
/Arc
引用可变。如果引用计数大于一,它们将 clone
内部值以确保唯一所有权;否则,它们将修改原始值。它们不经常需要,但在某些情况下可能非常有用。
示例 1,
示例 2。
Mutex
、RwLock
、Condvar
和 Once
parking_lot
crate 提供了这些同步类型的替代实现。parking_lot
类型的 API 和语义与标准库中等价类型的相似但不相同。
以前,parking_lot
版本通常比标准库中的版本更小、更快、更灵活,但在某些平台上,标准库版本已经有了很大的改进。因此,在切换到 parking_lot
之前应该先进行测量。
如果决定普遍使用 parking_lot
类型,很容易在某些地方意外使用标准库的等价类型。您可以使用 Clippy 来避免此问题。