什么是Rust的选项types的开销?
在Rust中,指针永远不能为null,所以如果实际上需要null的话,比如链表,可以使用Optiontypes:
struct element { value: i32, next: Option<Box<element>>, }
这涉及多less开销(就内存分配而言,以及与简单指针相比,取消引用的步骤)? 在编译器/运行库中是否有一些“魔术”,使得Option可以免费使用,或者比在非核心类库中使用Option实现成本更低(使用相同的enum
结构,或者将指针包装在向量)?
是的,有一些编译器魔术可以将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个字节):
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内的不可空指针优化!
注意:这个答案是最新的Rust 1.1
这个答案现在已经过时了, Option<T>
的判别式在可能的情况下现在被优化。 (尽pipe提供的其他信息仍然很有趣。)
目前, Option
types占用的空间量与其他任何enum
types相同。 我不知道具体情况,但肯定是代表某种歧视的工会。
Rust开发人员正在考虑调整内部表示以进行优化的可能性。
以下是帕特里克·沃尔顿(Patrick Walton)发布的有关Dev开发邮件列表的相关讨论 :
我有点犹豫是否承诺枚举的特定位表示,因为这里有很多编译器优化的空间。 例如,我们可能希望将
Option<~int>
折叠成一个可空指针,我们可能想将Result<(),~str>
折成可为空的string,或者我们可以将Either<u8,~str>
1个字,假设string不能占用地址空间的前256个字节。 我想了一会儿,也许最好只说Rust的枚举模式是不明确的,给我们尽可能多的空间来优化。