我正在阅读哈德利的高级R编程,当它讨论字符的内存大小时,它说:
R有一个全局字符串池。这意味着每个唯一的字符串
存储在一个地方,因此字符向量占用较少
记忆比你想象的要多。
书中给出的例子如下:

library(pryr)
object_size("banana")
#> 96 B
object_size(rep("banana", 10))
#> 216 B

本节的练习之一是比较这两个字符向量:
vec <- lapply(0:50, function(i) c("ba", rep("na", i)))
str <- lapply(vec, paste0, collapse = "")

object_size(vec)
13.4 kB

object_size(str)
8.74 kB

现在,由于这篇文章指出R有一个全局字符串池,并且由于vectorvec主要由两个字符串(“ba”和“na”)的重复组成,我实际上-直觉地-期望vec的大小小于str的大小。
所以我的问题是:你怎么能最准确地估计这些向量的大小呢?

最佳答案

关键区别在于vec中的指针:每个短标量字符串(charsxps)都必须从相应的字符串向量(strsxp)指向。您在vec中有1326个这样的字符串指针,但在str中只有51个(指针在您的平台上可能是8个字节)。池用于标量字符串(即charsxp缓存)。另一个不明显的因素是内部碎片,例如在我的系统中,标量字符串的大小相同,不管它是否有0到7个字符,8个字符的字符串只需要更多的字符,等等。重复的尺寸如下:
unlist(sapply(str, object.size))
[1]96 96 96 104 104 104 104 120 120 120 120 120 120 120 120 136 136 136
[20]136 136 136 152 152 152 152 152 152 152 152 216 216 216 216 216 216
[39]216 216 216 216 216 216 216 216 216 216 216 216 216 216
但是,这些是R的内存管理器的实现细节,可能会发生变化,并且在用户程序中不应该以任何方式依赖它们-对于另一个对象布局/内存管理器,str可以使用比vec更多的空间。

08-07 03:41