R存储真的会占很大空间吗?本文通过一些简单的示例带你接近真相。
我们利用lobstr::obj_size()
函数访问对象的大小。
obj_size(letters)
#> 1,712 B
obj_size(ggplot2::diamonds)
#> 3,456,344 B
在上一篇文章中介绍过列表存储的不是实际的值,而是指向值的引用,所以一个列表的大小比我们预期的可能要小的多。
x <- runif(1e6)
obj_size(x)
#> 8,000,048 B
y <- list(x, x, x)
obj_size(y)
#> 8,000,128 B
这里变量y
仅比变量x
大80个字节!这正是有3个空值的列表大小:
obj_size(list(NULL, NULL, NULL))
#> 80 B
相似地,R采用全局字符串池,所以字符串向量占用的内存比我们想象中要小的多,重复一个字符串1万次并不会占用相应1万倍的存储空间。
banana <- "bananas bananas bananas"
obj_size(banana)
#> 136 B
obj_size(rep(banana, 100))
#> 928 B
因为引用的使用,估计独立变量占用的内存将比较有挑战性。除非变量x
和变量y
没有共享元素,obj_size(x) + obj_size(y) = obj_size(x, y)
才会成立。
obj_size(x, y)
#> 8,000,128 B
最后,R v3.5.0版本开始引入了ALTREP, short for alternative representation,以:
符号指定的序列将不会记录所有的数值,而是记录这个序列,这让它所占用的内存更小了。下面的结果显示无论序列多大啊,占用的内存都是一样的!
obj_size(1:3)
#> 680 B
obj_size(1:1e3)
#> 680 B
obj_size(1:1e6)
#> 680 B
obj_size(1:1e9)
#> 680 B
不止我们在进步,编程语言也在进步喔!
内容整理自Advanced R。
网友评论