Standard Library Types

It is worth reading through the documentation for common standard library types—such as Vec, Option, Result, and Rc/Arc—to find interesting functions that can sometimes be used to improve performance.

It is also worth knowing about high-performance alternatives to standard library types, such as Mutex, RwLock, Condvar, and Once.

Vec

Vec::remove removes an element at a particular index and shifts all subsequent elements one to the left, which makes it O(n). Vec::swap_remove replaces an element at a particular index with the final element, which does not preserve ordering, but is O(1).

Vec::retain efficiently removes multiple items from a Vec. There is an equivalent method for other collection types such as String, HashSet, and HashMap.

Option and Result

Option::ok_or converts an Option into a Result, and is passed an err parameter that is used if the Option value is None. err is computed eagerly. If its computation is expensive, you should instead use Option::ok_or_else, which computes the error value lazily via a closure. For example, this:


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

should be changed to this:


#![allow(unused)]
fn main() {
fn expensive() {}
let o: Option<u32> = None;
let r = o.ok_or_else(|| expensive()); // evaluates `expensive()` only when needed
}

Example.

There are similar alternatives for Option::map_or, Option::unwrap_or, Result::or, Result::map_or, and Result::unwrap_or.

Rc/Arc

Rc::make_mut/Arc::make_mut provide clone-on-write semantics. They make a mutable reference to an Rc/Arc. If the refcount is greater than one, they will clone the inner value to ensure unique ownership; otherwise, they will modify the original value. They are not needed often, but they can be extremely useful on occasion. Example 1, Example 2.

Mutex, RwLock, Condvar, and Once

The parking_lot crate provides alternative implementations of these synchronization types that are smaller, faster, and more flexible than those in the standard library. The APIs and semantics of the parking_lot types are similar but not identical to those of the equivalent types in the standard library.

If you decide to universally use the parking_lot types it is easy to accidentally use the standard library equivalents in some places. You can use clippy to avoid this problem.