Сколько памяти занимают перечисления?
Вопрос
Например, если у меня есть перечисление с двумя падежами, занимает ли оно больше памяти, чем логическое значение?Языки:Java, C++
Решение
В Java, an enum
это полноценный класс:
Перечисляемые типы языка программирования Java намного мощнее, чем их аналоги на других языках.Объявление enum определяет класс (называется перечисляемым типом).Класс enum body может включать в себя методы и другие поля.
Для того, чтобы увидеть фактический размер каждого 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 в памяти должен быть только один экземпляр каждого из значений вашего перечисления.Затем для ссылки на перечисление требуется только хранилище для этой ссылки.Проверка значения перечисления так же эффективна, как и любое другое сравнение ссылок.
Вы могли бы беспокоиться об этом только при хранении большого количества перечислений.Для 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 ++ нет никаких обязательств по тому, чтобы перечисление было больше, чем требует его самый большой перечислитель.В частности, перечисление {TRUE, FALSE} может иметь размер sizeof(1), даже если sizeof(bool)==sizeof(int).Здесь просто нет никаких требований.Некоторые компиляторы делают перечисления того же размера, что и int.Это функция компилятора, которая разрешена, поскольку стандарт устанавливает только минимум.Другие компиляторы используют расширения для управления размером перечисления.
printf("%d", sizeof(enum));
В C ++ перечисление обычно имеет тот же размер, что и int
.Тем не менее, компиляторы нередко предоставляют переключатель командной строки, позволяющий установить размер перечисления на наименьший размер, соответствующий определенному диапазону значений.
Нет, перечисление обычно имеет тот же размер, что и int, такой же, как boolean.
Если в вашем перечислении когда-либо будет только два случая, действительно, использование логического значения вместо этого может быть лучшей идеей (размер памяти, производительность, использование / логика), тем более в Java.
Если вас интересует стоимость памяти, это может означать, что вы планируете использовать их много.В Java вы можете использовать класс BitSet, или, в меньшем масштабе, в обоих языках вы можете манипулировать битами с помощью побитовых операций.
sizeof (перечисление) зависит от того, что у вас есть в перечислении.Недавно я пытался найти размер ArrayList() с параметрами конструктора по умолчанию и без объектов, хранящихся внутри (что означает, что емкость для хранения равна 10).Оказалось, что ArrayList не слишком большой < 100 байт.
Итак, sizeof(перечисление) для очень простого перечисления должно быть меньше 10 байт.вы можете написать небольшую программу, выделить ей определенный объем памяти, а затем попробовать выделить перечисления.вы должны быть в состоянии понять это (вот как я узнал о памяти ArrayList)
БР,
~А
В C / C ++ перечисление будет иметь тот же размер, что и int.
С помощью gcc вы можете добавить атрибут((упаковано)) к определению enum, чтобы оно занимало минимум места.Если наибольшее значение в перечислении равно < 256 это будет один байт, два байта, если наибольшее значение равно < 65536 и т.д.
typedef enum {
MY_ENUM0,
MY_ENUM1,
MY_ENUM2,
MY_ENUM3,
MY_ENUM4,
MY_ENUM5
} __attribute__((packed)) myEnum_e;