From 06e7632cd5e730f284d5c965379a3a02810b0cce Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Mon, 30 Sep 2024 19:26:24 +0000 Subject: [PATCH] Reduce references to niche optimization Niche optimization is currently mentioned in three places: - Enums (User-Defined Types, Day 1 Afternoon) - Option (Standard Library Types, Day 2 Afternoon) - Box (Smart Pointers, Day 3 Morning) This is a tricky thing to get right, and it was just in the speaker notes in each place. #1820 will introduce a fuller explanation. --- src/smart-pointers/box.md | 36 ++++-------------------------------- src/std-types/option.md | 8 ++++++-- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/src/smart-pointers/box.md b/src/smart-pointers/box.md index b481f46ba27..c144a1d1132 100644 --- a/src/smart-pointers/box.md +++ b/src/smart-pointers/box.md @@ -32,7 +32,7 @@ fn main() { from `T` directly on a `Box`](https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-deref-coercion). Recursive data types or data types with dynamic sizes cannot be stored inline -without a pointer indirection, which can be worked around using `Box`: +without a pointer indirection. `Box` accomplishes that indirection: ```rust,editable #[derive(Debug)] @@ -86,36 +86,8 @@ fn main() { have to use indirection, a `Box` or reference of some kind, instead of storing the value directly. -# More to Explore - -## Niche Optimization - -Though `Box` looks like `std::unique_ptr` in C++, it cannot be empty/null. This -makes `Box` one of the types that allow the compiler to optimize storage of some -enums. - -For example, `Option>` has the same size, as just `Box`, because -compiler uses NULL-value to discriminate variants instead of using explicit tag -(["Null Pointer Optimization"](https://doc.rust-lang.org/std/option/#representation)): - -```rust,editable -use std::mem::size_of_val; - -struct Item(String); - -fn main() { - let just_box: Box = Box::new(Item("Just box".into())); - let optional_box: Option> = - Some(Box::new(Item("Optional box".into()))); - let none: Option> = None; - - assert_eq!(size_of_val(&just_box), size_of_val(&optional_box)); - assert_eq!(size_of_val(&just_box), size_of_val(&none)); - - println!("Size of just_box: {}", size_of_val(&just_box)); - println!("Size of optional_box: {}", size_of_val(&optional_box)); - println!("Size of none: {}", size_of_val(&none)); -} -``` +- Though `Box` looks like `std::unique_ptr` in C++, it cannot be empty/null. + This makes `Box` one of the types that allow the compiler to optimize storage + of some enums (the "niche optimization"). diff --git a/src/std-types/option.md b/src/std-types/option.md index a960dad7492..90321079048 100644 --- a/src/std-types/option.md +++ b/src/std-types/option.md @@ -30,7 +30,11 @@ fn main() { None. - It's common to `unwrap`/`expect` all over the place when hacking something together, but production code typically handles `None` in a nicer fashion. -- The niche optimization means that `Option` often has the same size in - memory as `T`. + +- The "niche optimization" means that `Option` often has the same size in + memory as `T`, if there is some representation that is not a valid value of T. + For example, a reference cannot be NULL, so `Option<&T>` automatically uses + NULL to represent the `None` variant, and thus can be stored in the same + memory as `&T`.