为什么这个Rust枚举不小? [英] Why is this Rust enum not smaller?
问题描述
考虑这个愚蠢的枚举:
enum Number {
Rational {
numerator: i32,
denominator: std::num::NonZeroU32,
},
FixedPoint {
whole: i16,
fractional: u16,
},
}
Rational变量中的数据占用8个字节,而FixedPoint变量中的数据占用4个字节. Rational变体的字段必须为非零,因此我希望枚举布局规则将其用作鉴别符,零表示存在FixedPoint变体.
The data in the Rational variant takes up 8 bytes, and the data in the FixedPoint variant takes up 4 bytes. The Rational variant has a field which must be nonzero, so i would hope that the enum layout rules would use that as a discriminator, with zero indicating the presence of the FixedPoint variant.
但是,这:
fn main() {
println!("Number = {}", std::mem::size_of::<Number>(),);
}
打印:
Number = 12
因此,枚举为显式区分符留有空间,而不是利用非零字段的存在.
So, the enum gets space for an explicit discriminator, rather than exploiting the presence of the nonzero field.
为什么编译器不能使这个枚举变小?
Why isn't the compiler able to make this enum smaller?
推荐答案
Although simple cases like Option<&T>
can be handled without reserving space for the tag, the layout calculator in rustc is still not clever enough to optimize the size of enums with multiple non-empty variants.
这是GitHub上的 issue#46213 .
This is issue #46213 on GitHub.
您询问的情况非常明确,但是在类似的情况下,枚举看起来应该被优化,但实际上并非如此,因为优化会排除采用内部变量的可能性.参考;例如,请参见为什么Rust只需要一个字节时,为什么使用两个字节来表示该枚举?
The case you ask about is pretty clear-cut, but there are similar cases where an enum looks like it should be optimized, but in fact can't be because the optimization would preclude taking internal references; for example, see Why does Rust use two bytes to represent this enum when only one is necessary?
这篇关于为什么这个Rust枚举不小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!