標準ライブラリ型
Vec、Option、Result、Rc/Arc などの一般的な標準ライブラリ型のドキュメントを一読しておく価値があります。パフォーマンスの改善に使えることがある興味深い関数を見つけられる場合があります。
Mutex、RwLock、Condvar、Once など、標準ライブラリ型に対する高性能な代替実装について知っておくことも価値があります。
Vec
長さ n のゼロ埋めされた Vec を作成する最良の方法は、vec![0; n] を使うことです。これは単純であり、おそらく resize、extend、あるいは unsafe を含むものなどの代替手段と比べて同等以上に高速です。OS の支援を利用できるためです。
Vec::remove は特定のインデックスにある要素を削除し、後続のすべての要素を 1 つ左にシフトするため、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 への可変参照を作成します。参照カウントが 1 より大きい場合、一意な所有権を保証するために内部の値を clone します。そうでない場合は、元の値を変更します。これらが必要になることは多くありませんが、場合によっては非常に有用です。
例 1、
例 2。
Mutex、RwLock、Condvar、Once
parking_lot クレートは、これらの同期型の代替実装を提供します。parking_lot 型の API とセマンティクスは、標準ライブラリ内の同等の型と似ていますが、同一ではありません。
parking_lot 版は、以前は標準ライブラリ版よりも確実に小さく、高速で、柔軟でした。しかし、標準ライブラリ版はいくつかのプラットフォームで大幅に改善されています。そのため、parking_lot に切り替える前に測定すべきです。
parking_lot 型を全面的に使用することにした場合でも、一部の場所で誤って標準ライブラリの同等の型を使用してしまうことは簡単に起こります。この問題を避けるには Clippy を使用できます。