[英]How much memory do Enums take?
例如,如果我有一個包含兩種情況的枚舉,它是否會占用比布爾值更多的內存? 語言:Java,C ++
在Java中, enum
是一個完整的類 :
Java編程語言枚舉類型比其他語言中的對應類型更強大。 枚舉聲明定義了一個類(稱為枚舉類型)。 枚舉類主體可以包括方法和其他字段。
為了查看每個enum
的實際大小,讓我們創建一個實際的enum
並檢查它創建的class
文件的內容。
假設我們有以下Constants
枚舉類:
public enum Constants {
ONE,
TWO,
THREE;
}
使用javap
編譯上面的enum
和反匯編生成的class
文件給出了以下內容:
Compiled from "Constants.java"
public final class Constants extends java.lang.Enum{
public static final Constants ONE;
public static final Constants TWO;
public static final Constants THREE;
public static Constants[] values();
public static Constants valueOf(java.lang.String);
static {};
}
反匯編表明enum
每個字段都是Constants
enum
類的一個實例。 (使用javap
進一步分析將揭示通過在靜態初始化塊中調用new Constants(String)
構造函數來創建新對象來初始化每個字段。)
因此,我們可以告訴我們創建的每個enum
字段至少與在JVM中創建對象的開銷一樣多。
在Java中,內存中每個枚舉值只應該有一個實例。 然后,對枚舉的引用僅需要該引用的存儲。 檢查枚舉的值與任何其他參考比較一樣有效。
存儲大量枚舉時,您只會擔心這一點。 對於Java,您可以在某些情況下使用EnumSet。 它在內部使用位向量,非常節省空間和快速。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html
bool
可以實現為單個字節,但通常在結構中它將被具有對齊要求的其他元素包圍,這意味着布爾值實際上將占用至少與int
一樣多的空間。
現代處理器從主存儲器加載數據作為整個高速緩存行,64字節。 從L1高速緩存加載一個字節和加載四個字節之間的區別可以忽略不計。
如果你試圖在一個非常高性能的應用程序中優化緩存行,那么你可能會擔心你的枚舉有多大,但通常我會說定義一個枚舉比使用一個布爾值更清楚。
在Java中,需要更多內存。 在C ++中,它不需要相同類型的常量所需的內存(它在編譯時計算並且在運行時沒有剩余重要性)。 在C ++中,這意味着枚舉的默認類型將占用與int相同的空間。
在ISO C ++中,枚舉沒有義務大於其最大的枚舉器要求。 特別是,即使sizeof(bool)== sizeof(int),枚舉{TRUE,FALSE}也可能具有sizeof(1)。 根本沒有要求。 有些編譯器使枚舉的大小與int相同。 這是一個編譯器功能,這是允許的,因為標准只強加了最小值。 其他編譯器使用擴展來控制枚舉的大小。
printf("%d", sizeof(enum));
在C ++中,枚舉通常與int
大小相同。 這就是說編譯器提供命令行開關以允許將枚舉的大小設置為適合定義的值范圍的最小大小並不罕見。
不,枚舉通常與int的大小相同,與布爾值相同。
如果你的枚舉只有兩種情況,那么確實使用布爾值可能是一個更好的想法(內存大小,性能,用法/邏輯),甚至更多用Java。
如果你想知道內存成本,可能意味着你計划使用它們。 在Java中,您可以使用BitSet類,或者在較小的范圍內,在兩種語言中都可以使用按位運算來操作位。
sizeof(enum)取決於你在枚舉中的含義。 我最近試圖使用默認構造函數params找到ArrayList()的大小,並且沒有存儲在其中的對象(這意味着存儲的容量是10)。 原來,ArrayList不是太大<100字節。
因此,一個非常簡單的枚舉的sizeof(enum)應小於10個字節。 你可以編寫一個小程序,給它一定的內存,然后嘗試分配枚舉。 你應該能夠搞清楚(這就是我如何找到ArrayList的內存)
BR,
〜一
在C / C ++中,枚舉與int的大小相同。
使用gcc,您可以將屬性 ((packed))添加到枚舉定義中,以使其占用最少的空間。 如果枚舉中的最大值<256,則這將是一個字節,如果最大值<65536,則為兩個字節,等等。
typedef enum {
MY_ENUM0,
MY_ENUM1,
MY_ENUM2,
MY_ENUM3,
MY_ENUM4,
MY_ENUM5
} __attribute__((packed)) myEnum_e;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.