2013-05-12 73 views
51

生锈,引用不能为空,所以在情况下,你确实需要空,如链接列表,您可以使用Option类型:Rust的选项类型的开销是多少?

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

多少开销参与这一在内存方面分配和步骤解引用相比,一个简单的指针?在编译器/运行库中有没有一些“魔力”可以使得Option免费,或者比使用相同enum构造的非核心库本身实现Option更便宜,或者成本更低,或者通过将指针包装在向量中?

回答

55

是的,有一些编译器魔术可以优化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内优化!

+17

此外,这种优化发生在所有类似“Option”的枚举中,所以它也适用于用户定义的Option。 – 2013-05-13 20:04:26

6

此答案现在已过时;在可能的情况下,Option<T>中的判别式现在被优化。(所提供的信息的其余部分仍然是有趣,虽然。)

现在,一个Option型占据的空间相同量的比任何其他enum类型。我不知道具体情况,但它确实代表某种有区别的工会。

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

这里是一个relevant discussion on the dev mailing list,张贴由帕特里克·沃尔顿:

我有点犹豫承诺的 枚举特定位表示,因为有大量的空间,在这里编译器的优化。对于 例如,我们可能要崩溃了Option<~int>成一个可空 指针,我们可能要崩溃了Result<(),~str>成一个可空 字符串,或者我们可能要崩溃了Either<u8,~str>到1个字, 假设弦永远不能占据前256个字节地址空间的 。我想了一会儿,也许最好 只是说,Rust枚举的位模式是未指定的,给我们尽可能多的空间来优化。

+1

这是不正确的。 (一些)你提到的优化已经[实施](https://github.com/mozilla/rust/pull/6001)。 – huon 2013-05-13 05:45:32

+1

好吧,就像你说的这是正确的当前发布版本的Rust :-) – barjak 2013-05-13 15:20:28