我不打算提高性能或内存使用率,这个问题纯粹是出于好奇。
主要问题
鉴于以下类,C#编译器(Mono + .NET)将两个short
变量打包成4个字节,还是消耗8个字节(带对齐)?
public class SomeClass {
short a;
short b;
}
次要问题
如果上述问题的答案不是4个字节,那么以下备选方案是否会提供任何优势(其中SomeClass
的使用量非常大):
// Warning, my bit math might not be entirely accurate!
public class SomeClass {
private int _ab;
public short a {
get { return _ab & 0x00ff; }
set { _ab |= value & 0x00ff;
}
public short b {
get { return _ab >> 8; }
set { _ab |= value << 8; }
}
}
答案 0 :(得分:6)
这取决于运行时,正如@David_M所说,但您可以使用[StructLayout]
属性强制它,该属性具有Pack
成员,您可以使用该属性来控制打包。或者,您可以使用[FieldOffset]
手动布局结构的成员(甚至重叠,这是您在.NET中实现联合的方式)。
答案 1 :(得分:5)
这取决于运行时,而不是编译器。您可以使用[StructLayout]
覆盖默认行为,这可能有所帮助 - 尽管默认行为应该没问题。
话虽如此,如果绝对要求最小化总大小,您可能需要考虑struct
而不是class
。使用类时,类的每个实例都会增加很多开销。在syncblk,TypeHandle等之间,以及引用(在64位系统上是另外8个字节)对象实例使用相当数量的&#34;额外&#34;记忆超越你的两条短裤。有关详细信息,请参阅"How the CLR Creates Runtime Objects"。
将数据存储到一组值类型中可以完全避免这种情况,并将实例总数保持在每个8字节(加上收集开销)。当然,这会改变使用方面的语义,但是如果你只使用两个短路,这将减少你的类型所涉及的开销量,特别是在64位系统上。
答案 2 :(得分:2)
实际布局取决于运行时,因为其他人已评论主要是因为您可以在多个平台上运行相同的代码。
是的,如果有很多物品可以节省空间。您正在寻找的是LayoutKind(StructLayout属性)。它可以让你随心所欲地打包成员。例如,使用Sequential,它将确保它紧凑。
[StructLayout(LayoutKind.Sequential)]
public class SomeClass {
short a;
short b;
}
有关详细信息,请查看MSDN- Structlayout