R - 为什么向数据 table 添加 1 列几乎使使用的峰值内存翻倍?

R - Why adding 1 column to data table nearly doubles peak memory used?

从 2 位好心的先生那里得到 后,我设法从 data frame+plyr 切换到数据 tables。

情况和我的问题

在我工作的过程中,我注意到当我添加 1 个新的 内存使用峰值 几乎翻了一番,从 3.5GB 到 6.8GB(根据 Windows 任务管理器)列使用 := 到我的数据集包含 ~200K 行乘以 2.5K 列。

然后我尝试了 200M 行乘 25 列,增加量从 6GB 增加到 7.6GB,然后在 gc().

后下降到 7.25GB

特别是关于添加新列,Matt Dowle 自己提到here

With its := operator you can :

Add columns by reference
Modify subsets of existing columns by reference, and by group by reference
Delete columns by reference

None of these operations copy the (potentially large) data.table at all, not even once.

问题1:如果data.table为2.5K列的DT,为什么添加单列'NAs'两倍使用的峰值内存完全没有复制?

问题2:为什么DT为200M x 25时不会倍增?我没有包括打印屏幕,但请随时更改我的代码并尝试。

使用测试代码打印内存使用情况

  1. 干净重新启动,RStudio 和 MS Word 打开 - 已使用 103MB

  2. Aft 运行 DT 创建代码但在添加列之前 - 使用了 3.5GB

  3. 添加 1 列后填充 NA,但在 gc() 之前 - 使用 6.8GB

  4. 在 运行 gc() 之后 - 使用了 3.5GB

测试码

为了调查,我编写了以下与我的数据集非常相似的测试代码:

library(data.table)
set.seed(1)

# Credit: Dirk Eddelbuettel's answer in 
# 
RandDate <- function(N, st="2000/01/01", et="2014/12/31") { 
  st <- as.POSIXct(as.Date(st))
  et <- as.POSIXct(as.Date(et))
  dt <- as.numeric(difftime(et,st,unit="sec"))
  ev <- runif(N, 0, dt)
  rt <- as.character( strptime(st + ev, "%Y-%m-%d") )
}

# Create Sample data
TotalNoCol <- 2500
TotalCharCol <- 3
TotalDateCol <- 1
TotalIntCol <- 600
TotalNumCol <- TotalNoCol - TotalCharCol - TotalDateCol - TotalIntCol
nrow <- 200000

ColNames = paste0("C", 1:TotalNoCol)

dt <- as.data.table( setNames( c(

  replicate( TotalCharCol, sample( state.name, nrow, replace = T ), simplify = F ), 
  replicate( TotalDateCol, RandDate( nrow ), simplify = F ), 
  replicate( TotalNumCol, round( runif( nrow, 1, 30 ), 2), simplify = F ), 
  replicate( TotalIntCol, sample( 1:10, nrow, replace = T ), simplify = F ) ), 

    ColNames ) )

gc()

# Add New columns, to be run separately
dt[, New_Col := NA ]  # Additional col; uses excessive memory?

研究完成

我没有发现太多关于 DT 的内存使用的讨论,有很多列,只有 this 但即便如此,它也不是专门关于内存的。

大多数关于大型数据集 + 内存使用的讨论都涉及行数很大但列数相对较少的 DT。

我的系统

英特尔 i7-4700 与 4-core/8-thread; 16GB DDR3-12800 内存; Windows 8.1 64 位; 500GB 7200rpm 硬盘; 64 位 R;数据 Table ver 1.9.4

免责声明

请原谅我使用 'non-R' 方法(即任务管理器)来测量使用的内存。 R 中的内存 measurement/profiling 是我还没有弄清楚的东西。


编辑 1:更新到数据 table ver 1.9.5 并重新 运行 后。不幸的是,问题仍然存在。

(我不能相信伟大的 DT 头脑(Arun)一直在研究这个并发现它与 print.data.table 有关。只是在这里为其他 SO 用户关闭循环.)

:= data.table 内存问题似乎已在 R 版本 3.2 上解决,如下所述: https://github.com/Rdatatable/data.table/issues/1062

[引用@Arun 来自 Github 问题 1062...]

fixed in R v3.2, IIUC, with this item from NEWS:

Auto-printing no longer duplicates objects when printing is dispatched to a method.

所以其他有这个问题的人应该考虑升级到 R 3.2。