yohhoyの日記

技術的メモをしていきたい日記

Option型とNull Pointer Optimization

Rust標準ライブラリが提供するヌル許容型 std::option::Option<T> の空間オーバーヘッドについてメモ。[本記事はRust 1.11/Stable準拠]

まとめ:

  • T型がポインタ的に振る舞う(有効値が非ゼロと保障できる)場合、ヌルポインタ最適化(null pointer optimization)*1によりOption<T>型はT型のサイズに等しい。内部的には値0をNone、非0値をSome(T)として扱う。
  • それ以外の場合(有効値0もとりうる型)の場合、T型の保持領域とは別に追加メモリが必要となる。Option<T>型のサイズはT型よりも大きくなる。
use std::mem::size_of;

fn main() {
  println!("i32      {} {}", size_of::<i32>(), size_of::<Option<i32>>());
  println!("&i32     {} {}", size_of::<&i32>(), size_of::<Option<&i32>>());
  println!("Box<i32> {} {}", size_of::<Box<i32>>(), size_of::<Option<Box<i32>>>());
}
// i32      4 8
// &i32     8 8
// Box<i32> 8 8

例えば整数型(i32)に対してはヌルポインタ最適化を適用できないが、参照型(&i32)やBox型(Box<i32>)では同最適化によりゼロ・オーバーヘッドが実現される。これは core::nonzero::NonZeroコンパイラ・マジックにより実現される。Rust 1.11/Stable現在、ユーザ定義型にはヌルポインタ最適化を適用できない。

  • 2018-08-04追記:Rust 1.25にて標準ライブラリstd::ptr::NunNullが、Rust 1.28にて標準ライブラリstd::num::NonZero*が安定化された。

関連URL

*1:同名称はRust公式ドキュメント "The Rustonomicon" 中で言及されている。