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

标签 c# performance memory enums

在 C# 中使用字节枚举进行小枚举是一种好处还是一种好的做法?
这会减少内存使用吗?
这能提高速度吗?
例子:

enum Fruits : byte { Apple, Orange, Banana }
与此相比有什么优势:
enum Fruits { Apple, Orange, Banana }
提前致谢。

最佳答案

使用 Visual Studio 机器代码窗口进行调查
对于 byte enumint enum我们可以看到内存对齐到4 bytes在 Windows x64 上的每种情况下,即使使用 Flags属性。但是long enum消费 8 bytes每个值。
因此没有必要使用字节枚举,因为它消耗相同的内存并且速度相同,并且使用字节对齐应该只在 8 位机器上有用。
说明
这是因为 .NET 在 x32 和 x64 Intel/AMD 上使用 32 位整数寄存器,即使使用 AnyCPU 或 x64 目标也是如此。
.NET 编译器不是针对内存进行优化,而是针对速度进行优化,因为处理器内部总线大小在 x32 CPU 上优化为 (16/)32 位,在 x64 CPU 上优化为 (32/)64 位。因此,32 位访问是 x32 上的最佳速度,64 位访问是 x64 上的最佳。任何其他尺寸“强制”处理器缩小/放大尺寸。我写了 (16/) 和 (32/) 是因为这些访问经过优化,比其他人缩小/放大大小要慢。
这是因为 .NET 编译器比内存更喜欢速度,特别是因为它是虚拟机,因此比 native 代码慢。出于兼容性原因,它支持 32 位。实际上,32 位寄存器和内存访问在 x32/x64 机器上得到了更多优化,而较低的对齐方式会导致性能损失(除非我们有 8 位或 16 位处理器)。如果编译 AnyCPU 或针对 x64,则只有内存指针在 x32 上为 32,在 x64 上为 64。
因此,任何短于 32 位的数据现在都应该与 32 位对齐,而在 future 可能是 64 位。
因此,在结构体和类中,比整数短的枚举以及小于或等于 4 字节大小的整数值是 4 字节对齐的,因此我们在 x32 或 x64 下的 .NET 机器上每字节丢失了 3 个字节,除非我们修改 struct packing size (默认为 4 个字节)。
评论
marshal sizeof在结构或类实例上给出了“已使用(非托管)数据大小”,但不是真正的保留内存,包括用于存储数据的丢失块。
示例

enum FruitsByte : byte { Apple, Orange, Banana }
enum FruitsInt { Apple, Orange, Banana }
enum FruitsLong : long { Apple, Orange, Banana }
对于字节
var fb1 = FruitsByte.Apple;
mov dword ptr [rbp+0A4h],ecx  

var fb2 = FruitsByte.Orange;
mov dword ptr [rbp+0A0h],1  

0xA4 - 0xA0 = 4 bytes
对于整数
var fi1 = FruitsInt.Apple;
mov dword ptr [rbp+9Ch],ecx  

var fi2 = FruitsInt.Orange;
mov dword ptr [rbp+98h],1  

0x9C - 0x98 = 4 bytes
长久
var fl1 = FruitsLong.Apple;
mov qword ptr [rbp+90h],rcx  

var fl2 = FruitsLong.Orange;
mov qword ptr [rbp+88h],rcx  

0x90 - 0x88 = 8 bytes
全机码
      var fb1 = FruitsByte.Apple;
00007FF7E93C0B19  xor         ecx,ecx  
00007FF7E93C0B1B  mov         dword ptr [rbp+0A4h],ecx  
      var fb2 = FruitsByte.Orange;
00007FF7E93C0B21  mov         dword ptr [rbp+0A0h],1  

      var fi1 = FruitsInt.Apple;
00007FF7E93C0B2B  mov         dword ptr [rbp+9Ch],ecx  
      var fi2 = FruitsInt.Orange;
00007FF7E93C0B31  mov         dword ptr [rbp+98h],1  

      var fl1 = FruitsLong.Apple;
00007FF7E93C0B3B  movsxd      rcx,ecx  
00007FF7E93C0B3E  mov         qword ptr [rbp+90h],rcx  
      var fl2 = FruitsLong.Orange;
00007FF7E93C0B45  mov         ecx,1  
00007FF7E93C0B4A  movsxd      rcx,ecx  
00007FF7E93C0B4D  mov         qword ptr [rbp+88h],rcx  
更多信息
Data structure alignment (Wikipedia)
x64 Architecture - CPU registers (MSDoc)
8086 to i486 Instructions Set
Intel® 64 and IA-32 Architectures Software Developer Manuals

关于c# - 多少内存使用字节枚举,这是否优化了 C# 中的内存/速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65546920/

相关文章:

DMA 上下文中的缓存一致性问题

java - 使用 JPA,方法需要 60 秒

c# - 使用ServiceStack和Signalr的Redis MQ

c# - AutoCAD 插件无法定位资源

c# - 如何在模型类中将 appsettings.json 文本作为 SQL 连接字符串传递? (具体例子)

performance - 在 VB6 中计时功能/测量性能的最佳方法是什么?

c - 最佳缓冲区大小

javascript - 将很长的变量从 PHP 传递到 Javascript

iOS内存似乎无缘无故地在应用程序中不断增加

c# - 如何以编程方式将 AD 组添加到 SharePoint 2010 SPGroup?