Rust的Option类型的开销是多少?

问题描述 投票:69回答:2

在Rust中,引用永远不能为null,因此如果您实际需要null,例如链表,则使用Option类型:

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

与简单指针相比,在内存分配和解除引用步骤方面涉及多少开销?在编译器/运行时中是否有一些“魔力”使Option免费,或者比使用相同的Option构造在非核心库中自己实现enum,或者将指针包装在向量中的成本更低?

performance rust null-pointer
2个回答
69
投票

是的,有一些编译器魔法可以将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

请注意,&i32Box&[i32]Vec<i32>都在Option中使用非可空指针优化!


7
投票

这个答案现在已经过时了; Option<T>中的判别现在尽可能优化。 (但提供的其他信息仍然很有趣。)

目前,Option类型占用的空间量与任何其他enum类型相同。我不知道具体细节,但它肯定表现为某种歧视的联盟。

Rust开发人员正在考虑调整内部表示以进行优化的可能性。

这是一张由Patrick Walton发布的relevant discussion on the dev mailing list

我对提交枚举的特定位表示有点犹豫,因为这里有很多编译器优化的空间。例如,我们可能想要将Option<~int>折叠为可空的指针,我们可能希望将Result<(),~str>折叠为可空字符串,或者我们可能希望将Either<u8,~str>折叠为1个字,假设字符串永远不会占用地址空间的前256个字节。我想了一段时间,也许最好只是说Rust枚举的位模式是未指定的,为我们提供尽可能多的空间来进行优化。

© www.soinside.com 2019 - 2024. All rights reserved.