【问题标题】:What is the overhead of Rust's Option type?Rust 的 Option 类型的开销是多少?
【发布时间】:2013-05-06 11:01:27
【问题描述】:

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

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

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

【问题讨论】:

    标签: performance rust null-pointer


    【解决方案1】:

    是的,有一些编译器魔法可以将 Option&lt;ptr&gt; 优化为单个指针(大部分时间)。

    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
    

    请注意,&amp;i32Box&amp;[i32]Vec&lt;i32&gt; 都在 Option 中使用不可空指针优化!

    【讨论】:

    • 此外,这种优化发生在所有“Option-like”枚举中,因此它也适用于用户定义的Option
    • 还要注意这个优化不能叠加。这可以在示例的最后一行中看到。当您将 Ok 的类型指定为 () 时,该特定结果类型将成为“类似枚举的选项”,因此无法在选项级别进行优化。但如果您尝试使用Result&lt;i32, i32&gt;,您会看到再次应用了优化。
    • @Pajn 看起来,至少截至 2020 年 3 月,this type of optimization can be stacked 只要有足够多的其他无效二进制表示。当然,不可为空的指针通常只有一种无效的二进制表示。
    猜你喜欢
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 2011-11-23
    • 2017-09-27
    • 1970-01-01
    • 2011-01-17
    • 2011-05-17
    • 2012-01-05
    相关资源
    最近更新 更多