【问题标题】:For saving a single large object in R, is saveRDS or save faster?对于在 R 中保存单个大对象,是 saveRDS 还是保存更快?
【发布时间】:2018-05-21 09:11:07
【问题描述】:

我目前有一个非常大的数组(500 个元素,每个元素都有一个 1000 x 20 的矩阵)。我一直在使用saveRDS 来保存对象。但是,这样做始终需要很长时间。我想知道save() 是否更快,或者每个选项中是否有选项可以更快地保存东西?谢谢。

【问题讨论】:

  • 矩阵对象列表还是 N 秩数组?
  • 嗨,我很抱歉,但它似乎不仅是矩阵对象的列表,而且是回归拟合输出的列表。我的列表名为My.List,它包含 500 个列表对象。因此,如果我调用“My.List[[1]]”,它会输出 1000 x 20 的矩阵以及回归拟合输出。
  • 查看此内容以获得更快的 saveRDS 替代方案:github.com/traversc/qs

标签: r


【解决方案1】:

您总是可以在来源中探索一下:

saveRDS():

function (object, file = "", ascii = FALSE, version = NULL, compress = TRUE, 
    refhook = NULL) {}
...
  .Internal(serializeToConn(object, con, ascii, version, refhook))
}

最终:https://github.com/wch/r-source/blob/2c3e0e757e81ca23c34da8dde4ff925bd9d275f0/src/main/serialize.c#L2471-L2536

save():

function (..., list = character(), file = stop("'file' must be specified"), 
    ascii = FALSE, version = NULL, envir = parent.frame(), compress = isTRUE(!ascii), 
    compression_level, eval.promises = TRUE, precheck = TRUE) {
...
  .Internal(saveToConn(list, con, ascii, version, envir,  eval.promises))
}

最终:https://github.com/wch/r-source/blob/6ac8f58c608337200f85ea47cba2abc717be6eb5/src/main/saveload.c#L1973-L2041

给它一个基准(假设它是一个矩阵对象列表):

library(microbenchmark)

set.seed(0)

lapply(1:500, function(i) {
  matrix(sample(20*1000), nrow = 1000, ncol = 20)
}) -> matrix_list

print(str(matrix_list, list.len=5))
## List of 500
##  $ : int [1:1000, 1:20] 17934 5310 7442 11456 18161 4033 17963 18887 13211 12577 ...
##  $ : int [1:1000, 1:20] 2227 4212 2296 2907 6198 3005 10531 2358 9543 15374 ...
##  $ : int [1:1000, 1:20] 5969 11861 11057 11933 7852 17959 14794 530 16811 17003 ...
##  $ : int [1:1000, 1:20] 1073 14634 12948 16282 2087 6687 7992 7640 18482 8043 ...
##  $ : int [1:1000, 1:20] 10900 8249 6059 10767 15541 17139 11663 9010 576 14900 ...
##   [list output truncated]
## NULL

pryr::object_size(matrix_list)
## 40.1 MB

microbenchmark(
  save = save(matrix_list, file = "/tmp/out.rda"),
  saveRDS = saveRDS(matrix_list, file = "/tmp/out.rds"),
  times = 5,
  control = list(warmup = 2)
) -> mb

mb
## Unit: seconds
##     expr      min       lq     mean   median       uq       max neval
##     save 8.571138 8.578461 8.747248 8.650629 8.665557  9.270453     5
##  saveRDS 8.647355 8.655231 9.298947 8.684998 8.772102 11.735052     5

您可以使用save() 中的compresscompression_level 设置以及gzcon() 中的level 设置,以便在saveRDS()compress 中使用,看看更改或删除压缩是否有帮助。

【讨论】:

  • 我希望较低的压缩级别或不压缩是最快的。硬件将决定幅度。
  • @JoshuaUlrich 这实际上取决于 (1) 您的硬件性能(CPU 与存储延迟),(2) 压缩实施的质量,(3) 数据的可压缩性。对于适度容易压缩的数据,高压缩应该提供更快的读写速度,即使在相对快速的存储介质上也是如此(也就是说,我知道现实情况有些不同……这部分是实施质量问题) .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 1970-01-01
相关资源
最近更新 更多