javaでは、EnumSetは、それに含まれる項目をlong
(RegularEnumSet
)またはlong[]
(JumboEnumSet
)を使用してビットマスク/ビットベクトルに格納します。私は今、多くの1000個のドメインオブジェクト(Node
と呼ぶ)を持っているユースケースに出くわしました。各オブジェクトは、オブジェクトごとに異なる順序で列挙型のすべての項目を表示します(Flag
としましょう)。Javaで列挙型の注文を格納する
現在、私はGuava ImmutableSet
として注文を保管しています。これは、その注文を保持するためです。しかし、EnumSet<Flag>
、ImmutableSet<Flag>
およびFlag[]
のメモリ使用量を比較するのにthe methods explained on this pageを使用しました。
)フラグ64の列挙項目を有し、b)は、3つのすべての変異体が全64の項目が含まれている場合、ここでの結果でありますEnumSetの:32バイト
のImmutableSet:832バイト
アレイ:272バイト
だから私の質問は:列挙型の順序を数値にパックする巧妙な方法は、メモリのフットプリントを配列のそれよりも小さくするためですか?違いがある場合:私の使用例では、注文には常にすべてのEnumアイテムが含まれていると仮定します。
明確にする:私の列挙型はそれよりもはるかに小さく、今のところメモリの問題はなく、この状況が私に記憶上の問題を与える可能性もありません。この非効率性は、この微視的なレベルでさえも私には不具合があります。
アップデート:私はバイト配列を使用してこのデータ構造を思い付いた
様々な回答やコメントからの提案の後。警告:Setインターフェイスは実装されていません(一意の値はチェックされません)、バイトが保持できるものを超える大きな列挙型には拡大されません。
public class EnumOrdering<E extends Enum<E>> implements Iterable<E> {
private final Class<E> type;
private final byte[] order;
public EnumOrdering(final Class<E> type, final Collection<E> order) {
this.type = type;
this.order = new byte[order.size()];
int offset = 0;
for (final E item : order) {
this.order[offset++] = (byte) item.ordinal();
}
}
@Override
public Iterator<E> iterator() {
return new AbstractIterator<E>() {
private int offset = -1;
private final E[] enumConstants = type.getEnumConstants();
@Override
protected E computeNext() {
if (offset < order.length - 1) {
return enumConstants[order[++offset]];
}
return endOfData();
}
};
}
}
メモリフットプリントは、次のとおりです:
EnumOrdering:104
Enum.valuesは、()( see here for a discussion of this problem)を繰り返し照会する必要があるが、ここに行くのでまた、複雑さは、かなりひどいです
これまでのところ、bestsssとJB Nizetのおかげでかなり良い結果でした!
アップデート:私だけにコードを変更している何か他のものに等しい/のhashCodeのための賢明な実装を必要とするので、反復処理可能を実装/含まれているなど
byte []の単純配列は、byte []にenum.ordinalを含みます。あなたが256以上のアイテムを持っているなら、短い[]/int []を使うことができます。あるいは、アイテムを8ビット未満にパックすることもできます。シリアライゼーションに特別な注意を払わなければならないかもしれませんが、どちらの方法でもコードは200行未満になりますが、それはかなり簡単です。 – bestsss
もしあなたが挿入命令を必要としないならば、ちょうど1つのlongを使うことができます。これはCで書かれたように、最大64個の要素を列挙することができます。 – bestsss
挿入順序が必要なければ@bestsss EnumSetは、正確には –