Memory 如何在Rust的枚举中找到最大的变体?
我正在努力提高rust程序的性能,这要求我减少一些大型Memory 如何在Rust的枚举中找到最大的变体?,memory,enums,rust,Memory,Enums,Rust,我正在努力提高rust程序的性能,这要求我减少一些大型enums的大小。比如说 枚举EE{ A、 //0 B(i32),//4 C(i64),//8 D(字符串),//24 E{//16 x:i64, y:i32, }, } fn main(){ println!(“{}”,std::mem::size_of::());//32 } 打印32。但是如果我想知道EE::A的大小,我会得到一个编译错误 错误[E0573]:应为类型,找到变量'EE::A` -->src/main.rs:14:40
enum
s的大小。比如说
枚举EE{
A、 //0
B(i32),//4
C(i64),//8
D(字符串),//24
E{//16
x:i64,
y:i32,
},
}
fn main(){
println!(“{}”,std::mem::size_of::());//32
}
打印32
。但是如果我想知道EE::A
的大小,我会得到一个编译错误
错误[E0573]:应为类型,找到变量'EE::A`
-->src/main.rs:14:40
|
14 | println!(“{}”,std::mem::size_of::());
| ^^^^^
| |
|不是一种类型
|帮助:尝试使用变量的枚举:`crate::EE`
错误:由于上一个错误而中止
错误:无法编译“播放”。
有没有办法找出哪个变量占用的空间最大?没有,没有办法只获得
枚举的一个变量的大小。您所能做的最好的事情就是获取变量所包含内容的大小,就像它是一个独立的结构一样:
println!("sizeof EE::A: {}", std::mem::size_of::<()>()); // 0
println!("sizeof EE::B: {}", std::mem::size_of::<i32>()); // 4
println!("sizeof EE::C: {}", std::mem::size_of::<i64>()); // 8
println!("sizeof EE::D: {}", std::mem::size_of::<String>()); // 24
println!("sizeof EE::E: {}", std::mem::size_of::<(i64, i32)>()); // 16
println!(“sizeof EE::A:{}”,std::mem::size_of::());//0
普林顿!(“sizeof EE::B:{}”,std::mem::size_of::());//4.
普林顿!(“sizeof EE::C:{}”,std::mem::size_of::());//8.
普林顿!(“sizeof EE::D:{}”,std::mem::size_of::());//24
普林顿!(“sizeof EE::E:{}”,std::mem::size_of::());//16
甚至这也不是特别有用,因为它包括可能用于存储标记的填充字节;正如您所指出的,如果D
缩小到一个指针,则enum
的大小可以减少到16,但仅从大小上看,您无法知道这一点。如果将y
定义为i64
,则每个变量的大小将相同,但enum
的大小需要为24。对齐是另一个混淆因素,它使得枚举的大小比“最大变量加上标记的大小”更复杂
当然,这都是高度依赖于平台的,您的代码不应该依赖任何具有特定布局的enum
(除非您可以用#[repr]
注释来保证)
如果您担心某个特定的enum
,那么获取每个包含类型的大小并不困难。Clippy还有一个用于enum
s的lint,变量之间的尺寸差异极大。但是,我不建议仅使用大小来对enum
布局进行手动优化,也不建议将大小仅为几个指针的东西装箱——间接抑制编译器可能能够执行的其他类型的优化。如果您优先考虑最小的空间使用,您可能会意外地使代码在此过程中慢得多。“是否有一种有效的方法来获取每个枚举变量的大小?”→ 所有变量都有相同的大小,即对应枚举的大小。@mcarton“所有变量都有相同的大小”,这取决于占用最多内存的变量的大小,如果我能快速找到该变量,我可以快速改进枚举定义。我想问一下如何快速找到该变量,很抱歉,我表达得不好。@mcarton在上面的例子中,D(String)
需要的内存大小最多,是24,所以枚举的大小是(24+8)=32。如果我用D(String)
替换D(Box)
,枚举的大小可以减少到16。如果rust能告诉我D(String)
使用24字节,这是一个很大的好处,这是所有变量中最大的一个,因此枚举大小应该是32字节,如果D(String)
的大小可以减小,枚举的大小也可以减小。@mcarton虽然您在技术上是正确的,但我认为您在吹毛求疵,很清楚OP的意图。甚至还有一个Clippy lint表示“枚举上变量之间的大大小差异”,因为有一个枚举大小和每个变量的空间利用率的概念。在类似示例的情况下,您也可以使用Box
,它与Box
基本相同,但只需要16字节,因此,整个枚举可以容纳24个,同时避免了双重间接寻址的成本。很少有好的理由使用框
。