Enumはどのくらいのメモリを消費しますか?
質問
たとえば、2つのケースを持つEnumがある場合、ブール値よりも多くのメモリを必要としますか?言語:Java、C ++
解決
Javaでは、 enum
は本格的なクラスです:
Javaプログラミング言語の列挙型 彼らよりもはるかに強力です 他の言語の対応物。の enum宣言はクラスを定義します (列挙型と呼ばれます)。列挙型クラス 本体にはメソッドやその他の フィールド。
各class
の実際のサイズを確認するには、実際のConstants
を作成し、作成したjavap
ファイルの内容を調べてみましょう。
次のnew Constants(String)
enumクラスがあるとします:
public enum Constants {
ONE,
TWO,
THREE;
}
上記の<=>をコンパイルし、結果の<=>ファイルを<=>で逆アセンブルすると、次の結果が得られます。
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 {};
}
逆アセンブリは、<=>の各フィールドが<=> <=>クラスのインスタンスであることを示しています。 (<=>をさらに分析すると、静的初期化ブロックで<=>コンストラクターを呼び出して新しいオブジェクトを作成することにより、各フィールドが初期化されることがわかります。)
したがって、作成する各<=>フィールドは、少なくともJVMでオブジェクトを作成するオーバーヘッドと同程度になることがわかります。
他のヒント
Javaでは、enumの各値の1つのインスタンスのみがメモリに存在する必要があります。列挙型への参照には、その参照用のストレージのみが必要です。列挙の値を確認することは、他の参照比較と同じくらい効率的です。
大量の列挙型を保存する場合にのみ、これについて心配するでしょう。 Javaの場合、場合によってはEnumSetを使用できる場合があります。内部でビットベクトルを使用しているため、スペース効率が非常に高く、高速です。
http://java.sun。 com / j2se / 1.5.0 / docs / api / java / util / EnumSet.html
bool
はシングルバイトとして実装される場合がありますが、通常構造体では、ブール値がint
と少なくとも同じスペースを実質的に占有することを意味するアライメント要件を持つ他の要素に囲まれます。 。
最新のプロセッサは、キャッシュライン全体として64バイトのメインメモリからデータをロードします。 L1キャッシュから1バイトをロードする場合と4バイトをロードする場合の違いはごくわずかです。
非常に高性能なアプリケーションでキャッシュラインを最適化しようとしている場合、enumの大きさを心配するかもしれませんが、一般的に、ブール値を使用するよりもenumを定義する方が明確だと思います。
Javaでは、より多くのメモリが必要になります。 C ++では、同じ型の定数に必要なメモリを必要としません(コンパイル時に評価され、実行時に重要な意味を持ちません)。 C ++では、これは、enumのデフォルトの型がintと同じスペースを占めることを意味します。
ISO C ++では、enumがその最大の列挙子に必要なサイズより大きくなる義務はありません。特に、sizeof(bool)== sizeof(int)の場合でも、enum {TRUE、FALSE}はsizeof(1)を持つ場合があります。単に要件はありません。一部のコンパイラは、enumをintと同じサイズにします。これはコンパイラの機能であり、標準では最小値のみが課されているため許可されています。他のコンパイラは、拡張機能を使用して列挙のサイズを制御します。
printf("%d", sizeof(enum));
C ++では、enumは通常、int
と同じサイズです。ただし、定義された値の範囲に適合する最小サイズに列挙のサイズを設定できるコマンドラインスイッチをコンパイラが提供することは珍しくありません。
いいえ、enumは通常ブール値と同じintと同じサイズです。
enumに2つのケースしかない場合、実際にはJavaの代わりにブール値を使用するほうが良いかもしれません(メモリサイズ、パフォーマンス、使用法/ロジック)。
メモリコストについて疑問がある場合は、それらの多くを使用する計画があることを意味する場合があります。 Javaでは、両方の言語でBitSetクラスを使用するか、小規模で使用できますが、ビット単位の操作でビットを操作できます。
sizeof(enum)は、列挙型に依存します。私は最近、デフォルトのコンストラクターパラメーターを使用して、内部にオブジェクトを格納しないArrayList()のサイズを見つけようとしました(つまり、格納する容量は10です)。 ArrayListが大きすぎないことが判明しました<!> lt; 100バイト。
したがって、非常に単純な列挙型のsizeof(enum)は10バイト未満でなければなりません。小さなプログラムを作成し、一定量のメモリを与えてから列挙型を割り当ててみてください。あなたはそれを理解することができるはずです(それは私がArrayListのメモリを見つけた方法です)
BR、
〜A
C / C ++では、enumはintと同じサイズになります。
gccを使用すると、列挙型定義に attribute ((packed))を追加して、フットプリントを最小限に抑えることができます。列挙型の最大値が<!> ltの場合; 256これは1バイト、最大値が<!> ltの場合は2バイトになります。 65536など。
typedef enum {
MY_ENUM0,
MY_ENUM1,
MY_ENUM2,
MY_ENUM3,
MY_ENUM4,
MY_ENUM5
} __attribute__((packed)) myEnum_e;