(следующее относится к GHC, другие компиляторы могут использовать другие соглашения о хранении)
Практическое правило: конструктор стоит одно слово для заголовка и одно слово для каждого поля .Исключение: конструктор без полей (например, Nothing
или True
) не занимает места, потому что GHC создает один экземпляр этих конструкторов и разделяет его среди всех применений.
Слово составляет 4 байта на32-разрядный компьютер и 8 байт на 64-разрядном компьютере.
Например,
data Uno = Uno a
data Due = Due a b
Uno
занимает 2 слова, а Due
- 3 *. 1016*
Тип Int
теперь определяется как
data Int = I# Int#
, Int#
занимает одно слово, поэтому Int
- 2.Большинство распакованных типов принимают одно слово, за исключением Int64#
, Word64#
и Double#
(на 32-разрядной машине), которые занимают 2. GHC на самом деле имеет кэш малых значений типа Int
и Char
, поэтому во многих случаях они вообще не занимают места в куче.Для String
требуется только место для ячеек списка, если вы не используете Char
s> 255.
Int8
имеет идентичное представление Int
.Integer
определяется следующим образом:
data Integer
= S# Int# -- small integers
| J# Int# ByteArray# -- large integers
, поэтому небольшое Integer
(S#
) занимает 2 слова, а большое целое занимает переменное количество места в зависимости от его значения.ByteArray#
занимает 2 слова (заголовок + размер) плюс пробел для самого массива.
Обратите внимание, что конструктор, определенный с помощью newtype
, свободен .newtype
это просто идея времени компиляции, и она не занимает места и не требует никаких инструкций во время выполнения.
Подробнее в Расположение объектов кучи в комментарии GHC .