Що таке накладні витрати на тип опції Rust?


85

У Rust посилання ніколи не можуть бути нульовими, тому у випадку, коли вам насправді потрібне null, наприклад, пов'язаний список, ви використовуєте Optionтип:

struct Element {
    value: i32,
    next: Option<Box<Element>>,
}

Скільки накладених на це витрат з точки зору виділення пам’яті та кроків до розмежування порівняно з простим покажчиком? Чи існує якась "магія" у компіляторі / середовищі виконання, щоб зробити її Optionбезкоштовною або менш затратною, ніж якщо б її самостійно реалізувати Optionв непрофільній бібліотеці, використовуючи ту саму enumконструкцію, або обернувши покажчик у вектор?

Відповіді:


88

Так, існує деяка магія компілятора, яка оптимізується Option<ptr>до єдиного вказівника (більшу частину часу).

use std::mem::size_of;

macro_rules! show_size {
    (header) => (
        println!("{:<22} {:>4}    {}", "Type", "T", "Option<T>");
    );
    ($t:ty) => (
        println!("{:<22} {:4} {:4}", stringify!($t), size_of::<$t>(), size_of::<Option<$t>>())
    )
}

fn main() {
    show_size!(header);
    show_size!(i32);
    show_size!(&i32);
    show_size!(Box<i32>);
    show_size!(&[i32]);
    show_size!(Vec<i32>);
    show_size!(Result<(), Box<i32>>);
}

Друкуються такі розміри (на 64-бітній машині, тому покажчики мають 8 байт):

// As of Rust 1.22.1
Type                      T    Option<T>
i32                       4    8
&i32                      8    8
Box<i32>                  8    8
&[i32]                   16   16
Vec<i32>                 24   24
Result<(), Box<i32>>      8   16

Зверніть увагу , що &i32, Box, &[i32], Vec<i32>будь-використання не-обнуляє оптимізації покажчик всередині Option!


38
Крім того, ця оптимізація відбувається у всіх " Optionподібних" переліченнях, тому вона також буде працювати для визначених користувачем Option.
Paul Stansifer

4
Також зверніть увагу, що цю оптимізацію неможливо скласти. Це видно з останнього рядка у прикладі. Коли ви вказуєте тип для Ok як (), цей конкретний тип результату стає "опцією типу enum" і тому не може бути оптимізований на рівні опції. Але якщо ви спробуєте, Result<i32, i32>ви побачите, що оптимізація застосовується знову.
Pajn

5
@Pajn Схоже, щонайменше станом на березень 2020 р. Цей тип оптимізації може бути складений до тих пір, поки буде достатньо недійсних двійкових подань. Звичайно, ненульовані покажчики зазвичай мають лише одне недійсне двійкове представлення.
Ваелус
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.