haw*_*eye 4 byte haskell heap-memory
假设我有字符串
"abc"
Run Code Online (Sandbox Code Playgroud)
我想计算它在内存中占用的字节数。
我可以做:
import Data.Bits
finiteBitSize ("abc" :: [Char])
Run Code Online (Sandbox Code Playgroud)
但这会中断,因为[Char]该功能不支持该类型。(也是位而不是字节,但重点是画一张我要寻找的图片)。
我的问题是:我们可以在Haskell中编写一个函数来测量n个字符的字符串占用的字节数吗?
Dan*_*ner 14
情况很复杂。
让我们谈谈GHC,String尤其是关于GHC的讨论,并假设它已经过全面评估,因此我们没有以GC友好的方式迭代使用它,也没有延迟评估并存储一个小的thunk表示。巨大的数据结构。
在做出所有简化的假设之后,我们将需要了解一些定义。
type String = [Char]
data [a] = [] | a : [a] -- pseudosyntax
data Char = C# Char# -- I'm guessing, couldn't find a canonical source
Run Code Online (Sandbox Code Playgroud)
现在,我们将使用一些经验法则。首先:未装箱的东西(例如Char#)通常存储在一个机器字中。我们生活在一个64位计算机的世界中,因此Char#大约8个字节,即使它可能仅使用了它的最低4个字节。第二:数据构造函数是一个用来说出哪个构造函数的单词,再加上一个指向每个字段的单词。
现在我们准备好了。
空字符串是[],对于构造函数来说是一个单词,对于字段来说没有单词,因此总共一个单词。
非空字符串是c : cs,因此,对于:构造函数来说,是一个字c,要指向的是cs一个字,对于C#构造函数来说,是一个字,对于构造函数来说,一个字是,对于Char#。这是5个字,加上我们需要的许多字cs。
因此,对于String长度为n的a,我们有5 * n个词来表示的主体,String而对于终止符则有一个额外的词[]。实际上,每个字符40个字节!kes。
现在,您知道为什么打包表示Text(例如,或在适当时使用ByteString)如此重要。