有多少内存使用字节枚举,这是否优化了 C# 中的内存/速度?

Rie*_*era 5 c# memory performance enums

在 C# 中使用字节枚举进行小型枚举是一种好处还是一种好的做法?

这会减少内存使用吗?

这会提高速度吗?

例子:

enum Fruits : byte { Apple, Orange, Banana }
Run Code Online (Sandbox Code Playgroud)

相比之下有什么好处:

enum Fruits { Apple, Orange, Banana }
Run Code Online (Sandbox Code Playgroud)

提前致谢。

小智 3

使用 Visual Studio 机器代码窗口进行调查

\n

对于byte enum并且我们可以看到,即使使用该属性,在每种情况下内存都在 Windows x64 上int enum对齐。但按价值消费。4 bytesFlagslong enum8 bytes

\n

因此没有必要使用字节枚举,因为它消耗相同的内存并且速度相同,并且使用字节对齐应该仅在 8 位机器上有用。

\n

解释

\n

这是因为 .NET 在 x32 以及 x64 Intel/AMD 上使用 32 位寄存器来存储整数,即使对于 AnyCPU 或 x64 目标也是如此。

\n

.NET 编译器不会针对内存进行优化,而是针对速度进行优化,因为处理器内部总线大小在 x32 CPU 上优化为 (16/)32 位,在 x64 CPU 上优化为 (32/)64 位。因此,32 位访问是 x32 上的最佳速度,64 位访问是 x64 上的最佳速度。任何其他尺寸都会“强制”处理器减小/增大尺寸。我写了 (16/) 和 (32/),因为这些访问经过优化,比其他缩小/放大大小的速度要慢。

\n

这是因为 .NET 编译器更看重速度而不是内存,特别是因为它是虚拟机,因此比本机代码慢。出于兼容性原因,它更倾向于 32 位。事实上,32 位寄存器和内存访问在 x32/x64 机器上更加优化,较低的对齐会导致性能损失(除非我们有 8 位或 16 位处理器)。如果编译为 AnyCPU 或面向 x64,则仅内存指针在 x32 上为 32,在 x64 上为 64。

\n

因此,现在任何短于 32 位的数据都应该与 32 位对齐,将来可能会是 64 位。

\n

因此,比整数短的枚举以及结构和类中小于或等于 4 字节大小的整数值是 4 字节对齐的,因此我们在 x32 或 x64 下的 .NET 机器上每个字节丢失 3 个字节,除非我们修改结构打包大小(默认为 4 个字节)。

\n

评论

\n

元帅尺寸给出“已使用的(非托管)数据大小”,但不是真正的保留内存,包括用于存储数据的丢失块。

\n

例子

\n
enum FruitsByte : byte { Apple, Orange, Banana }\nenum FruitsInt { Apple, Orange, Banana }\nenum FruitsLong : long { Apple, Orange, Banana }\n
Run Code Online (Sandbox Code Playgroud)\n

对于字节

\n
var fb1 = FruitsByte.Apple;\nmov dword ptr [rbp+0A4h],ecx  \n\nvar fb2 = FruitsByte.Orange;\nmov dword ptr [rbp+0A0h],1  \n\n0xA4 - 0xA0 = 4 bytes\n
Run Code Online (Sandbox Code Playgroud)\n

对于整数

\n
var fi1 = FruitsInt.Apple;\nmov dword ptr [rbp+9Ch],ecx  \n\nvar fi2 = FruitsInt.Orange;\nmov dword ptr [rbp+98h],1  \n\n0x9C - 0x98 = 4 bytes\n
Run Code Online (Sandbox Code Playgroud)\n

长久以来

\n
var fl1 = FruitsLong.Apple;\nmov qword ptr [rbp+90h],rcx  \n\nvar fl2 = FruitsLong.Orange;\nmov qword ptr [rbp+88h],rcx  \n\n0x90 - 0x88 = 8 bytes\n
Run Code Online (Sandbox Code Playgroud)\n

完整机器码

\n
      var fb1 = FruitsByte.Apple;\n00007FF7E93C0B19  xor         ecx,ecx  \n00007FF7E93C0B1B  mov         dword ptr [rbp+0A4h],ecx  \n      var fb2 = FruitsByte.Orange;\n00007FF7E93C0B21  mov         dword ptr [rbp+0A0h],1  \n\n      var fi1 = FruitsInt.Apple;\n00007FF7E93C0B2B  mov         dword ptr [rbp+9Ch],ecx  \n      var fi2 = FruitsInt.Orange;\n00007FF7E93C0B31  mov         dword ptr [rbp+98h],1  \n\n      var fl1 = FruitsLong.Apple;\n00007FF7E93C0B3B  movsxd      rcx,ecx  \n00007FF7E93C0B3E  mov         qword ptr [rbp+90h],rcx  \n      var fl2 = FruitsLong.Orange;\n00007FF7E93C0B45  mov         ecx,1  \n00007FF7E93C0B4A  movsxd      rcx,ecx  \n00007FF7E93C0B4D  mov         qword ptr [rbp+88h],rcx  \n
Run Code Online (Sandbox Code Playgroud)\n

更多信息

\n

数据结构对齐(维基百科)

\n

x64 架构 - CPU 寄存器 (MSDoc)

\n

8086 至 i486 指令集

\n

Intel\xc2\xae 64 和 IA-32 架构软件开发人员手册

\n