在Rust中,引用永远不能为null,因此如果您确实需要null,例如链接列表,则使用Option
类型:
struct Element {
value: i32,
next: Option<Box<Element>>,
}
与简单指针相比,内存分配和解除引用步骤涉及多少开销?在编译器/运行时中是否存在一些“魔力”使Option
免费,或者比使用相同{{1}在非核心库中自己实现Option
的成本更低构造,或通过将指针包装在向量中?
答案 0 :(得分: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
请注意,&i32
,Box
,&[i32]
,Vec<i32>
都在Option
内使用非可空指针优化!
答案 1 :(得分: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枚举的位模式未指定,给出 我们尽可能多地利用优化空间。