Haskell数据类型的内存占用
我如何找到在Haskell中存储某种数据类型的值所需的实际内存量(主要是使用GHC)? 是否可以在运行时对其进行评估(例如,在GHCi中)还是可以从其组件评估复合数据类型的内存需求?
  通常,如果类型a和b内存需求是已知的,代数数据类型的内存开销是多少,例如: 
data Uno = Uno a
data Due = Due a b
例如,这些值占用内存中有多少字节?
1 :: Int8
1 :: Integer
2^100 :: Integer
x -> x + 1
(1 :: Int8, 2 :: Int8)
[1] :: [Int8]
Just (1 :: Int8)
Nothing
据我所知,由于垃圾回收延迟,实际内存分配较高。 由于懒惰评估可能会有显着差异(并且thunk大小与值的大小无关)。 问题是,在数据类型的情况下,完全评估时它的值需要多少内存?
  我发现GHCi中有一个:set +s选项来查看内存统计信息,但不清楚如何估计单个值的内存占用量。 
(以下适用于GHC,其他编译器可能使用不同的存储约定)
  经验法则: 一个构造函数为一个标题花费一个单词,每个字段花费一个单词 。  例外:没有字段的构造函数(如Nothing或True )不会占用空间,因为GHC会创建这些构造函数的单个实例并在所有用途中共享它。 
一个字在32位机器上是4个字节,而在64位机器上是8个字节。
所以例如
data Uno = Uno a
data Due = Due a b
  Uno需要2个单词, Due需要3个。 
  Int类型定义为 
data Int = I# Int#
  现在, Int#需要一个字,所以Int总共需要2个字。  大多数unboxed类型需要一个单词,例外是Int64# , Word64#和Double# (在32位机器上),它们需要2个.GHC实际上具有Int和Char类型的小值缓存,所以在许多情况下,这些根本不占用堆空间。  除非使用Char s> 255,否则String只需要列表单元格的空间。 
  Int8具有与Int相同的表示形式。  Integer定义如下: 
data Integer
  = S# Int#                            -- small integers
  | J# Int# ByteArray#                 -- large integers
  所以一个小Integer ( S# )需要2个字,但是一个大整数需要一个可变数量的空间,具体取决于它的值。  一个ByteArray#需要2个字(头+大小)加上数组本身的空间。 
  请注意, 用newtype定义的构造函数是免费的 。  newtype纯粹是编译时的想法,它不占用空间,在运行时不需要任何指令。 
有关GHC评论中堆对象布局的更多详细信息。
ghc-datasize包提供recursiveSize函数来计算GHC对象的大小。 然而...
垃圾收集在计算大小之前执行,因为垃圾收集器会使堆走难以执行。
...所以经常打电话是不实际的!
另请参阅如何查找GHC的数据类型的内存表示? 以及如何确定Haskell中类型的大小?
链接地址: http://www.djcxy.com/p/80197.html上一篇: Memory footprint of Haskell data types
下一篇: Python: How to estimate / calculate memory footprint of data structures?
