Chi phí của loại Rust's Option là gì?


84

Trong Rust, các tham chiếu không bao giờ có thể là null, vì vậy trong trường hợp bạn thực sự cần null, chẳng hạn như danh sách được liên kết, bạn sử dụng Optionkiểu:

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

Bao nhiêu chi phí liên quan đến điều này về cấp phát bộ nhớ và các bước để bỏ qua so với một con trỏ đơn giản? Có "phép thuật" nào đó trong trình biên dịch / thời gian chạy để làm cho không Optiontốn chi phí hoặc ít tốn kém hơn so với việc một người tự thực hiện Optiontrong một thư viện không lõi bằng cách sử dụng cùng một enumcấu trúc hoặc bằng cách bao bọc con trỏ trong một vectơ?

Câu trả lời:


87

Có, có một số phép thuật trình biên dịch tối ưu hóa Option<ptr>cho một con trỏ duy nhất (hầu hết thời gian).

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>>);
}

Các kích thước sau được in (trên máy 64 bit, vì vậy con trỏ là 8 byte):

// 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

Lưu ý rằng &i32, Box, &[i32], Vec<i32>tất cả sử dụng các phi nullable con trỏ tối ưu hóa bên trong một Option!


38
Hơn nữa, tối ưu hóa này xảy ra trong tất cả các Optionenums "giống như", vì vậy nó cũng sẽ hoạt động cho người dùng xác định Option.
Paul Stansifer

3
Cũng lưu ý rằng tối ưu hóa này không thể được xếp chồng lên nhau. Điều này có thể được nhìn thấy ở dòng cuối cùng trong ví dụ. Khi bạn chỉ định loại cho Ok là (), loại kết quả cụ thể đó sẽ trở thành một "tùy chọn như enum" và do đó không thể được tối ưu hóa ở cấp tùy chọn. Nhưng nếu bạn thử với Result<i32, i32>bạn có thể thấy rằng tối ưu hóa được áp dụng một lần nữa.
Pajn

4
@Pajn Có vẻ như, ít nhất là kể từ tháng 3 năm 2020, loại tối ưu hóa này có thể được xếp chồng lên nhau miễn là có đủ các biểu diễn nhị phân không hợp lệ. Tất nhiên, con trỏ không thể nullable thường chỉ có một biểu diễn nhị phân không hợp lệ.
Vaelus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.