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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了R中字符的对象大小 - R全局字符串池如何工作?相关的知识,希望对你有一定的参考价值。

我正在阅读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的大小。

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

答案

关键区别在于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更多的空间。

以上是关于R中字符的对象大小 - R全局字符串池如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

字符串池管理

如何更改 R 的指数符号约定的指数字符的大小写

R CMD检查中的全局变量注释没有可见的绑定

对于JVM中方法区,永久代,元空间以及字符串常量池的迁移和string.intern方法

常用内置对象

阿里面试题:字符串对象在JVM中是如何存放的