Почему логика потребляет 4 байта и char 2 байта в .NET framework? Булевое значение должно занимать 1 бит или, по меньшей мере, меньше, чем char.
Почему логическое устройство потребляет больше памяти, чем char?
Ответ 1
Это вопрос выравнивания памяти. 4-байтные переменные работают быстрее, чем 2-байтовые. Вот почему вы должны использовать int вместо байта или short для счетчиков и т.п.
Вы должны использовать переменные в 2 байта только тогда, когда память больше беспокоит, чем скорость. И вот почему char (который является Unicode в .NET) принимает два байта вместо четырех.
Ответ 2
О boolean
Большинство других ответов ошибочны - выравнивание и скорость - это то, почему программист должен придерживаться int для счетчиков циклов, а не почему компилятор может сделать байт шириной 4 байта. Фактически все ваши рассуждения применимы к байтам, а также к короткому, а также к булевому.
В С#, по крайней мере, bool (или System.Boolean) представляет собой встроенную структуру шириной 1 байт, которая может быть автоматически вставлена в коробку, поэтому у вас есть объект (для которого требуется, по крайней мере, два слова памяти, т.е. 8/16 байт в средах с 32/64 битками соответственно) с полем (по крайней мере один байт) плюс одно слово памяти, чтобы указать на него, то есть в целом не менее 13/25 байт.
Это действительно первая запись Google на "примитивных типах С#". http://msdn.microsoft.com/en-us/library/ms228360(VS.80).aspx
Также цитированная ссылка (http://geekswithblogs.net/cwilliams/archive/2005/09/18/54271.aspx) также указывает, что логическое значение по стандарту CLI занимает 1 байт.
На самом деле, однако, единственное место, где это видно, - это массивы булевых: n логических элементов будет занимать n байтов. В других случаях одно логическое значение может занимать 4 байта.
- Внутри структуры большинство runtimes (также в Java) выровняли все поля с 4-байтовой границей для производительности. Монти JVM для встроенных устройств более мудрый - я думаю, он перестраивает поля оптимально.
- В стеке локальных фреймов/операндов для интерпретатора в большинстве случаев для производительности одна запись в стеке - это одно слово памяти (и, возможно, на .NET она должна быть 64-битной шириной для поддержки двойной и длинной, что на .NET использует только 1 запись стека вместо 2 в Java). Компилятор JIT может вместо этого использовать 1 байт для логических локалей, сохраняя при этом другие vars, выровненные по переупорядочиванию полей без влияния на производительность, если это потребует дополнительные накладные расходы.
О char
char
- это два байта, потому что, когда требуется поддержка интернационализации, использование двухбайтовых символов является самой безопасной ставкой. Это напрямую не связано с выбором поддержки Unicode, а для выбора придерживаться UTF-16 и базовой многоязычной плоскости. В Java и С# вы можете предположить, что один логический char вписывается в переменную типа char.
Ответ 3
Это потому, что в 32-битной среде CPU может обрабатывать 32-битные значения быстрее, чем 8-битные или 16-битные значения, поэтому это компромисс скорости и размера. Если вам нужно сохранить память, и у вас есть большое количество bools, просто используйте uints и сохраните логические значения в виде битов из 4 байтов. Ширины имеют ширину 2 байта, так как они сохраняют 16-разрядные символы Unicode.
Ответ 4
Независимо от незначительной разницы в памяти, использование значений Boolean для истинных/ложных да/нет важно для разработчиков (включая вас самих, когда вам нужно повторно ознакомиться с кодом через год), поскольку он более точно отражает ваше намерение. Сделать код более понятным гораздо важнее, чем сохранить два байта.
То, что ваш код более точно отражает ваше намерение, также уменьшает вероятность того, что некоторая оптимизация компилятора будет иметь отрицательный эффект. Этот совет выходит за рамки платформ и компиляторов.
Ответ 5
Вы также должны использовать boolean, чтобы помочь написать управляемый код. Если я смотрю на код, видя, что что-то является логическим, более того стоит экономить память, чтобы понять, что вы используете char как booleans.
Ответ 6
Я нашел это: "На самом деле логическое значение - 4 байта, а не 2. Причина в том, что CLR поддерживает Boolean. Я думаю, что он делает, потому что 32-битные значения намного эффективнее манипулировать, поэтому вы должны использовать класс бит-бит (забудьте, где он), если вам нужно замять кучу бит вместе..."
Это написано Полом Виком в http://geekswithblogs.net/cwilliams/archive/2005/09/18/54271.aspx
Ответ 7
Память - это только проблема, если у вас есть большой массив бит, и в этом случае вы можете использовать класс System.Collections.BitArray.
Ответ 8
Прежде всего, вы должны использовать профилировщик, чтобы определить, где у вас проблема с памятью, IMHO.
Ответ 9
Потому что Windows и .Net использовали Unicode (UTF 16) с момента их создания в качестве внутреннего набора символов. UTF 16 использует 2 байта на символ или пару двухбайтовых слов на символ, но только если требуется, так как это кодировка ширины переменной.
"Для символов в базовой многоязычной плоскости (BMP) результирующая кодировка представляет собой одно 16-разрядное слово. Для символов в других плоскостях кодировка приведет к паре 16-битных слов"
Мое предположение относительно булевых элементов будет состоять из четырех байтов, так как регистр по умолчанию - 32 бита, и это будет минимальный размер .Net может эффективно выполнять логическую операцию, если только не использует побитовые операции.