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