1

我已经看到默认情况下,R包会drake保存每个目标的所有缓存。有时,一个目标只是从前一个目标中选择一些列,但如果数据真的很大,这意味着你会得到两个非常大的保存目标。此外,如果您稍微更改目标,我认为会drake保存该目标的新副本但保留之前的目标。这意味着每次调用都r_make一致地节省了缓存,从而积累了大量内存。

  • 有什么方法可以选择drake保存的目标吗?
  • 有没有办法避免保留目标缓存文件的历史记录?

这个积累在我的机器中占据了超过 45GB,这似乎很遥远。

谢谢

4

1 回答 1

3

高效的数据格式

首先,如果您的目标是数据帧(或data.tables),请考虑使用自定义“fst”(或“fst_dt”)格式保存这些目标:https ://github.com/ropensci/drake/pull/977 。目标将占用更少的空间并节省更多时间。这是一个快速的胜利。

目标应该是什么?

其次,让我们谈谈您提出的两个目标并没有那么不同的场景。

library(drake)
library(dplyr)

drake_plan(
  raw = get_raw_data(),
  data = select(-funds) %>%
    filter(spending < 900),
  analysis = analyze(data)
)
#> # A tibble: 3 x 2
#>   target   command                                  
#>   <chr>    <expr>                                   
#> 1 raw      get_raw_data()                           
#> 2 data     select(-funds) %>% filter(spending < 900)
#> 3 analysis analyze(data)

reprex 包(v0.3.0)于 2019 年 10 月 22 日创建

raw并且data基本上是彼此的副本,而且它们很大。如果你只raw用来计算data,我们可以跳过raw并定义我们自己的函数直接进入data。以下计划将使用更少的存储空间。

library(drake)
library(dplyr)

get_data <- function() {
  get_raw_data() %>%
    select(-funds) %>%
    filter(spending < 900)
}

drake_plan(
  data = get_data(),
  analysis = analyze(data)
)
#> # A tibble: 2 x 2
#>   target   command       
#>   <chr>    <expr>        
#> 1 data     get_data()
#> 2 analysis analyze(data)

reprex 包(v0.3.0)于 2019 年 10 月 22 日创建

以这种方式定义和使用函数是一种很好的做法。它不仅可以帮助您对选择的目标更具战略性,还可以使您的计划更易于阅读。

需要仔细考虑才能确定什么是目标以及目标内部的步骤是什么。一个理想的目标是

  1. 大到可以消耗大量运行时间,并且
  2. 足够小以至于make()倾向于跳过它,并且
  3. 对您的项目有意义。

列选择通常太快,无法证明创建一个全新的目标是合理的。

管理缓存

drake的缓存storr在后端使用,它不存储重复的对象。但是,它确实会存储目标,以防您尝试使用make(recover = TRUE). 但是,如果您的缓存变得太大,您可以使用垃圾收集删除这些历史目标,使用drake_gc()drake_cache()$gc()

减轻存储的其他技巧是history = FALSE,log_progress = FALSErecoverable = FALSEin make()。最后这些并没有减少整体存储大小,但确实减少了缓存中小文件的数量。

至于内存,手册中有一章:https ://ropenscilabs.github.io/drake-manual/memory.html 。为了减少会话内存消耗,您可以选择自定义内存策略并选择garbage_collection = TRUEin make()

于 2019-10-22T13:05:45.863 回答