簡體   English   中英

使 C# 枚舉內存高效?

[英]Make C# enums memory efficient?

根據這個問題,C# 將為Fruits類型的字段分配4 byte大小,是否定義如下:

enum Fruits : byte { Apple, Orange, Banana }

或像這樣:

enum Fruits { Apple, Orange, Banana }

我仍然很好奇是否有任何方法可以回避這一點並使 enum 的大小小於4 bytes 我知道這可能不是非常有效或可取的,但知道它是否可能仍然很有趣。

數據對齊(通常在124字節邊界上)用於更快地訪問數據( int應該在4字節邊界上對齊)。

例如(讓我使用byteint而不是enum提高可讀性struct而不是class - 這是在sizeof的幫助下獲取 struct 大小的簡單方法):

// sizeof() == 8 == 1 + 3 (padding) + 4
public struct MyDemo {
  public byte A; // Padded with 3 unused bytes 
  public int B;  // Aligned on 4 byte
}

// sizeof() == 8 == 1 + 1 + 2 (padding) + 4
public struct MyDemo {
  public byte A; // Bytes should be aligned on 1 Byte Border 
  public byte B; // Padded with 2 unused bytes
  public int C;  // Aligned on 4 byte
}

// sizeof() == 2 == 1 + 1 
public struct MyDemo {
  public byte A; // Bytes should be aligned on 1 Byte Border 
  public byte B; // Bytes should be aligned on 1 Byte Border 
}

到目前為止,即使在classstruct )中的字段的情況下,您也可以產生效果,例如

public MyClass {
  // 4 Byte in total: 1 + 1 + 2 (we are lucky: no padding here)
  private Fruits m_Fruits; // Aligned on 1 Byte border
  private byte m_MyByte    // Aligned on 1 Byte border
  private short m_NyShort; // Aligned on 2 Byte border
}

在集合(數組)的情況下,所有值都是相同的類型,應該以相同的方式對齊,這就是不需要填充的原因:

// Length * 1Byte == Length byte in total
byte[] array = new [] {
  byte1, // 1 Byte alignment
  byte2, // 1 Byte alignment
  byte3, // 1 Byte alignment
  ...
  byteN, // 1 Byte alignment
} 

根據這個問題,C#將為 Fruits 類型的字段分配 4 字節大小,無論它是這樣定義的

我會說這不是實際寫在那里的內容。 該帖子描述了堆棧上的內存對齊方式,它似乎也為byte變量對齊了 4 個字節(可能取決於平台):

byte b = 1;

產生與var fb1 = FruitsByte.Appleint i = 1;相同的IL_0000: ldc.i4.1指令; (參見sharplab.io )和移動指令中相同的4字節差異(x86上的Core CLR 6.0.322.12309)。

盡管使用相應的枚舉作為結構字段會導致它們與相應的邊框對齊:

Console.WriteLine(Unsafe.SizeOf<C>()); // prints 2
Console.WriteLine(Unsafe.SizeOf<C1>()); // prints 8

public enum Fruits : byte { Apple, Orange, Banana }
public enum Fruits1 { Apple, Orange, Banana }
public struct C {
    public Fruits f1;
    public Fruits f2;
}
public struct C1 {
    public Fruits1 f1;
    public Fruits1 f2;
}

數組也會發生同樣的情況,它將分配連續的內存區域而不對齊不同的元素。

有用的閱讀:

對於絕大多數應用程序來說,大小開銷根本不重要。 對於一些專門的應用程序,比如圖像處理,使用常量字節值並進行位操作可能是有意義的。 這也可以是一種將多個值打包到單個字節中的方法,或者將標志位與值組合:

const byte Apple = 0x01;
const byte Orange= 0x02;
const byte Banana= 0x03;
const byte FruitMask = 0x0f; // bits 0-3 represent the fruit value
const byte Red = 0x10;
const byte Green = 0x20;
const byte ColorMask = 0x70; // bits 4-6 represents color
const byte IsValidFlag = 0x80; // bit 7 represent value flag

...
var fruitValue = myBytes[i] & FruitMask;
var IsRed = (myBytes[i] & ColorMask) == Red ;
var isValid = myBytes[i] & IsValidFlag > 0;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM