R高效编程:matrix、data.table与data.frame内存性能差异问询
近期我需要开展数据量远超内存容量的大数据分析工作,因此重点关注内存优化相关技巧。我在技术社区看到两类常见建议:一是在不需要存储多数据类型列的场景下,matrix的表现优于data.frame;二是data.table的执行效率更高。我没有计算机专业背景,希望能深入理解三者的优劣势,而非仅停留在表面结论层面。
测试过程与结果
我基于iris数据集做了三组对照测试,具体过程和结果如下:
测试1:全数值列场景
第一组测试仅选取iris前4列全数值列,保证三类结构存储的数据类型一致,排除类型转换带来的干扰:
library(data.table) # 仅选取iris前4列全数值数据,保证对比基准一致 test1 <- iris[,1:4] test2 <- as.data.table(iris[,1:4]) test3 <- as.matrix(iris[,1:4]) # 统计各对象内存占用 sort(sapply(ls(),function(x){object.size(get(x))}))
测试得到的内存占用结果(单位:字节):
test3 test1 test2 5528 5920 6568
从结果看,全数值场景下matrix内存占用最低,其次是data.frame,data.table内存占用最高。基于这个结果我有两个核心疑问:
- 是不是数据存储框架的灵活性越高,需要的额外内存开销就越大?
data.table的效率优势是不是主要体现在数据处理速度上,而非存储层面的内存效率?
测试2:混合数据类型列场景
第二组测试纳入iris全部列,包含数值型、因子/字符型列:
rm(list = ls()) test1 <- iris test2 <- as.data.table(iris) test3 <- as.matrix(iris) sort(sapply(ls(),function(x){object.size(get(x))}))
测试结果:
test1 test2 test3 7256 7976 11128
纳入非数值列后,matrix因为要求所有列数据类型一致,会将全量数据统一转换为字符型存储,内存占用远高于另外两者,和我之前看到的“matrix内存更优”的结论存在明显差异。
测试3:全字符列场景
为了验证数据类型对内存占用的影响,我将所有列强制转换为字符型后再次测试:
library(dplyr) test1 <- iris %>% mutate_all(as.character) test2 <- iris %>% mutate_all(as.character) %>% as.data.table() test3 <- as.matrix(iris) sort(sapply(ls(),function(x){object.size(get(x))}))
测试结果:
test3 test1 test2 11128 14328 15048
当强制data.frame和data.table全列存储为字符型时,matrix的内存占用优势再次显现。
初步结论与待确认问题
基于上述小数据集测试,我目前得到的初步判断是:
- 纯单一数据类型(尤其是数值型)场景下,
matrix的内存占用最低 data.table的内存占用和data.frame接近,公开资料普遍提到它的处理速度更快,但我没有自行开展速度测试验证- 不同数据类型本身的内存开销差异很大,比如字符型的内存开销显著高于数值型;如果数据中存在少量字符列,用
data.frame或data.table存储更合适——因为matrix会强制把全量数据转成内存开销更高的字符型,反而抵消了本身的存储结构优势
目前我还有不确定的点:上述测试都是基于iris这类小型数据集完成的,不清楚在更大规模的数据集下,data.frame和data.table的内存表现差异是否会进一步扩大。
欢迎大家提出相关看法、补充意见,纠正我可能存在的认知偏差。
内容的提问来源于stack exchange,提问作者hhattiecc

