R data.table内存高效rbindlist

时间:2017-11-07 16:36:13

标签: r list memory data.table

我想以内存有效的方式对多个数据表进行处理。

更确切地说,我想逐个对它们进行攻击,并随时随地释放内存,以便我可以加入 n data.tables大小 k 当我的记忆只有(n + 1)* k 时。

我写了这个函数希望这样做:

rbindlistOneByOne <- function(l, use.names=FALSE, fill=FALSE, idcol=NULL, verbose = F) {
  ll <- length(l)
  # Handle empty lists
  if(ll <= 0) stop("rbindlistOneByOne : empty list")
  if(ll <= 1) return(l[[1]])
  # Handle normal lists (ll > 2)
  current <- l[[1]]
  res <- current
  l[1] <- NULL
  rm(current); gc()
  for(i in 2:ll) {
    current <- l[[1]]
    res <- rbindlist(list(res, current), use.names = use.names, fill = fill, idcol = idcol)
    l[1] <- NULL
    rm(current); gc()
  }
  return(res)
}

现在问题是这个函数不是内存效率,即使我认为它会。

你知道为什么吗?是因为rm没有释放内存,而且data.table称为&#34; current&#34;留在记忆中?

1 个答案:

答案 0 :(得分:1)

没有办法做你想做的事。内存释放在R中是随机的,你无法控制它。使用gc()可能会也可能不会释放内存,而且不受用户控制。

来自http://adv-r.had.co.nz/memory.html

  

尽管你可能已经在其他地方阅读过,但是从来没有必要自己调用gc()。 R会在需要更多空间时自动运行垃圾收集;如果你想知道什么时候,请调用gcinfo(TRUE)。您可能想要调用gc()的唯一原因是要求R将内存返回给操作系统。但是,即使这可能没有任何影响:旧版本的Windows无法让程序将内存返回到操作系统。

另外,调用gc非常慢。这里有一个函数的bechmark,有和没有调用gc的1000个10行表的列表

  • 没有gc:8毫秒
  • gc:7 s

rbindlist是绑定data.table

的最有效方式