Сколько памяти занимает Enums? - PullRequest
47 голосов
/ 27 сентября 2008

Например, если у меня есть Enum с двумя кейсами, он потребует больше памяти, чем логическое значение? Языки: Java, C ++

Ответы [ 12 ]

44 голосов
/ 27 сентября 2008

В Java enum является полноценным классом :

Типы перечислений языка программирования Java гораздо мощнее, чем их аналоги на других языках. Объявление enum определяет класс (называется типом enum). Enum класс Тело может включать в себя методы и другие поля.

Чтобы увидеть фактический размер каждого enum, давайте создадим фактический enum и изучим содержимое создаваемого им файла class.

Допустим, у нас есть следующий Constants enum class:

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.

17 голосов
/ 27 сентября 2008

В Java должен быть только один экземпляр каждого из значений вашего перечисления в памяти. Ссылка на перечисление тогда требует только хранения для этой ссылки. Проверка значения перечисления так же эффективна, как и любое другое эталонное сравнение.

8 голосов
/ 27 сентября 2008

Вы будете беспокоиться об этом только при хранении большого количества перечислений. Для Java вы можете использовать EnumSet в некоторых случаях. Он использует внутренний битовый вектор, который очень компактен и быстр.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html

7 голосов
/ 27 сентября 2008

bool может быть реализован как один байт, но обычно в структуре он будет окружен другими элементами, которые имеют требования к выравниванию, что будет означать, что логическое значение будет эффективно занимать по крайней мере столько же места, сколько int .

Современные процессоры загружают данные из основной памяти в виде всей строки кэша, 64 байта. Разница между загрузкой одного байта из кэша L1 и загрузкой четырех байтов незначительна.

Если вы пытаетесь оптимизировать строки кэша в очень высокопроизводительном приложении, вы можете беспокоиться о том, насколько велико ваше перечисление, но в целом я бы сказал, что определить перечисление яснее, чем использовать логическое значение.

4 голосов
/ 27 сентября 2008

На Java это заняло бы больше памяти. В C ++ не потребовалось бы никакой памяти, чем требовалось для константы того же типа (она оценивается во время компиляции и не имеет остаточного значения во время выполнения). В C ++ это означает, что тип по умолчанию для перечисления будет занимать то же место, что и int.

3 голосов
/ 29 сентября 2008

В ISO C ++ не существует обязательства для enum быть больше, чем требует его самый большой перечислитель. В частности, enum {TRUE, FALSE} может иметь sizeof (1), даже если sizeof (bool) == sizeof (int). Там просто нет требования. Некоторые компиляторы делают перечисления того же размера, что и int. Это функция компилятора, которая разрешена, потому что стандарт налагает только минимум. Другие компиляторы используют расширения для контроля размера перечисления.

1 голос
/ 28 сентября 2008

В C ++ перечисление обычно такого же размера, как int. Тем не менее, компиляторы нередко предоставляют параметр командной строки, чтобы размер перечисления мог быть установлен на наименьший размер, который соответствует диапазону определенных значений.

1 голос
/ 27 сентября 2008
printf("%d", sizeof(enum));
0 голосов
/ 28 сентября 2008

В C / C ++ перечисление будет того же размера, что и int.

С помощью gcc вы можете добавить атрибут ((упакованный)) к определению перечисления, чтобы он занимал минимальную площадь. Если наибольшее значение в перечислении <256, это будет один байт, два байта, если наибольшее значение <65536 и т. Д. </p>

typedef enum {
    MY_ENUM0,
    MY_ENUM1,
    MY_ENUM2,
    MY_ENUM3,
    MY_ENUM4,
    MY_ENUM5
} __attribute__((packed)) myEnum_e;
0 голосов
/ 27 сентября 2008

sizeof (enum) зависит от того, что у вас есть в enum. Недавно я пытался найти размер ArrayList () с параметрами конструктора по умолчанию и без объектов, хранящихся внутри (что означает, что емкость для хранения равна 10). Оказалось, что ArrayList не слишком большой <100 байт. </p>

Итак, sizeof (enum) для очень простого перечисления должен быть менее 10 байтов. Вы можете написать небольшую программу, выделить ей определенный объем памяти и затем попытаться выделить перечисления. Вы должны быть в состоянии понять это (вот как я узнал память ArrayList)

BR
~ A

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...