She*_*ter 28 optimization rust
当你有一个时Option<&T>,编译器就知道它NULL永远不是一个可能的值&T,而是将None变量编码为NULL.这样可以节省空间:
use std::mem;
fn main() {
assert_eq!(mem::size_of::<&u8>(), mem::size_of::<Option<&u8>>());
}
Run Code Online (Sandbox Code Playgroud)
但是,如果使用非指针类型执行相同操作,则不会有额外的位来存储该值,并且需要额外的空间:
use std::mem;
fn main() {
// fails because left is 1 and right is 2
assert_eq!(mem::size_of::<u8>(), mem::size_of::<Option<u8>>());
}
Run Code Online (Sandbox Code Playgroud)
一般来说,这是正确的.但是,我想选择加入优化,因为我知道我的类型有某些不可能的值.作为一个例子,我可能有一个有年龄的玩家角色.年龄可能未知,但永远不会高255:
struct Age(u8);
struct Player {
age: Option<Age>,
}
Run Code Online (Sandbox Code Playgroud)
我希望能够通知优化器这个约束 - Age永远不会255,因此使用该位模式是安全的None.这可能吗?
DK.*_*DK. 21
从Rust 1.28开始,您可以使用std::num::NonZeroU8(和朋友).它充当一个包装器,告诉编译器数字的内容永远不会包含文字零.这也是Option<Box<T>>指针大小的原因.
这是一个示例,说明如何创建Age和读取其有效负载.
use std::num::NonZeroU8;
struct Age(NonZeroU8);
impl Age {
pub fn new(age: u8) -> Age {
let age = NonZeroU8::new(age).expect("Age cannot be zero!");
Age(age)
}
pub fn age(&self) -> u8 {
self.0.get()
}
}
struct Player {
age: Option<Age>,
}
fn main() {
println!("size: {}", std::mem::size_of::<Player>());
// Output: size: 1
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2341 次 |
| 最近记录: |