如何在 R 中正确地对 load/readRDS 的速度进行基准测试?

How to benchmark speed of load/readRDS correctly in R?

我正在考虑将数据高效读入 R 并尝试了几种方法来测试 load('file.Rdata')readRDS('file.rds') 是否更快。文件 file.Rdatafile.rds 包含相同的数据,第一个用 save(d, 'file.Rdata', compress=F) 创建,第二个saveRDS(d, 'file.rds', compress=F).

首先我使用函数 microbenchmark() 并且对输出的最大值感到惊讶。

第一次测试:

library(microbenchmark)
microbenchmark(
    n <- readRDS('file.rds'),
    load('file.Rdata')
)


Unit: milliseconds
expr                      min        lq          mean        median      uq          max          neval
n <- readRDS('file.rds')  106.5956   109.6457    237.3844    117.8956    141.9921    10934.162    100
load(fl2)                 295.0654   301.8162    335.6266    308.3757    319.6965    1915.706     100

看起来最大值是异常值。

所以我尝试了: 第二次测试:

sapply(1:10, function(x) system.time(n <- readRDS('file.rds'))[3])
elapsed  elapsed  elapsed  elapsed  elapsed  elapsed  elapsed  elapsed  elapsed  elapsed 
10.50    0.11     0.11     0.11     0.10     0.11     0.11     0.11     0.12     0.12 

sapply(1:10, function(x) system.time(load'flie.Rdata'))[3])
elapsed  elapsed  elapsed  elapsed  elapsed  elapsed  elapsed  elapsed  elapsed  elapsed
1.86     0.29     0.31     0.30     0.30     0.31     0.30     0.29     0.31     0.30

这证实了我的怀疑;第一次加载数据比后面的时间要长得多。我怀疑这与数据的分配方式有关,如果第二次读取数据,R 不必 'fully' 读取数据。

那么问题来了,我怎样才能做一个现实的基准测试呢?从第一个测试中我得出结论,读取 *.rds 文件的速度更快。但这仅适用于大量的 neval。如果我设置 times = 1 那么读取 *.Rdata 会更快(正如第二个测试所示)。

感谢任何帮助或意见。

亲切的问候

我从 R-help@r-project.org 列表中得到了一些回复,我试着在这里总结一下。所有答案都可以找到here and here.

根据 William Dunlap 强制垃圾回收的想法,我最终得到以下代码:

library(microbenchmark)
mb <- microbenchmark(
    gc1 <- gc(),
    n <- readRDS('file.rds'),
    rm(n),
    gc2 <- gc(),
    load('file.Rdata'),
    rm(objectRdata),
    gc3 <- gc(),
    times=1000, control = list(order="inorder", warmup=4)
)

但是,当用mb$time[mb$expr=="d <- readRDS('file.rds')"]mb$time[mb$expr=="load('file.Rdata')"]提取时间时,它仍然是第一个值,比后面的都大得多。奇怪的是,第一次使用 readRDS 读取数据最长(大约 10 秒),而第一次使用 load 加载数据大约需要 2 秒。 readRDS 的以下读数约为 0.14 秒,而 load 需要 0.32 秒。

到目前为止,文件存储在服务器上。我对本地存储在 C: 上的文件进行了同样的尝试。

当 reading/loading 本地文件时,所有读数都更接近 readRDS 的 0.14 秒与 load

的 0.33 秒的较小值

总结一下。 reading/loading 取决于文件位置,未压缩文件的 readRDSload 快。但是请记住 Ismail Sezen 在 R-help@r-project.org:

上给出的答案

Why are there 2 functions called readRDS and load?

Because they have different purposses. You use _load _function to read/load bulk saved variables by save function and you use readRDS function to read/load a single variable saved by saveRDS function. So, it is inevitable both functions are optimized for different purposes. This is something like compare apple and pear altough both are fruits. Sometimes you want to eat apple but sometimes pear.

Aas a result, if I need to save and read a single R object, I prefer readRDS/saveRDS couple. If I need to serialize multiple object to a file, I use the load/save couple.