R中字符的对象大小 - R全局字符串池如何工作?

问题描述 投票:8回答:1

我正在阅读Hadley的高级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具有全局字符串池,并且因为向量vec主要由两个字符串(“ba”和“na”)的重复组成,所以我实际上 - 直觉地 - 期望vec的大小小于str的大小。

所以我的问题是:你怎么能最准确地预先估计这些矢量的大小?

r memory vector character
1个回答
1
投票

关键区别在于vec中的指针:每个短标量字符串(CHARSXP)必须从相应的字符串向量(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 136

[20] 136 136 136 136 152 152 152 152 152 152 152 152 216 216 216 216 216 216 216

[39] 216 216 216 216 216 216 216 216 216 216 216 216 216

然而,这些是R的内存管理器的实现细节可以改变,并且不应该以任何方式依赖于用户程序 - 使用另一个对象布局/内存管理器,str可以使用比vec更多的空间。

© www.soinside.com 2019 - 2024. All rights reserved.