Моя первая идея состояла в том, чтобы использовать эту аккуратную функцию litte , благодаря Саймону Марлоу:
{-# LANGUAGE MagicHash,UnboxedTuples #-}
module Size where
import GHC.Exts
import Foreign
unsafeSizeof :: a -> Int
unsafeSizeof a =
case unpackClosure# a of
(# x, ptrs, nptrs #) ->
sizeOf (undefined::Int) + -- one word for the header
I# (sizeofByteArray# (unsafeCoerce# ptrs)
+# sizeofByteArray# nptrs)
Использование:
Prelude> :!ghc -c Size.hs
Size.hs:15:18:
Warning: Ignoring unusable UNPACK pragma on the
third argument of `BitVec257'
In the definition of data constructor `BitVec257'
In the data type declaration for `BitVec257'
Prelude Size> unsafeSizeof $! BitVec514 (BitVec257 1 2 True 3 4) (BitVec257 1 2 True 3 4)
74
(Обратите внимание, что GHCговорит вам, что не может распаковать Bool
, так как это тип суммы.)
Вышеупомянутая функция утверждает, что ваш тип данных использует 74 байта на 64-битной машине.Я считаю, что трудно поверить.Я ожидаю, что тип данных будет использовать 11 слов = 88 байт, одно слово на поле.Даже Bool
s берут одно слово, так как они являются указателями на (статически размещенные) конструкторы.Я не совсем уверен, что здесь происходит.
Что касается выравнивания, я считаю, что каждое поле должно быть выровнено по словам.