与在 RStudio 中使用 saveRDS 相关的时间问题

Posted

技术标签:

【中文标题】与在 RStudio 中使用 saveRDS 相关的时间问题【英文标题】:Timing issue related to using saveRDS in RStudio 【发布时间】:2019-03-31 23:25:22 【问题描述】:

在执行循环之前调用 saveRDS 会导致循环时序不一致。这仅在使用 RStudio 时很明显;使用 Rscript 从命令行运行相同的脚本时,该问题不存在。这可能是 RStudio 中延迟 I/O 刷新的结果。

其他人是否注意到了这种行为? 有没有办法在 saveRDS 调用后强制刷新 I/O?

在 Ubuntu 18.04LTS 64 位上使用 RStudio 1.1.463、R 3.5.2。

我通过在代码执行之前调用 gc() 并使用 gcinfo 启用 gc 消息以确保不触发 gc 来消除垃圾收集器的问题。我还尝试使用 cmpfun 预编译该函数;这也无济于事。

以下代码可用于重现该问题。

loop.test <- function() 
  t <- c()
  t0 <- Sys.time()
  for (i in 1:10) 
    t <- c(t, Sys.time() - t0)
    Sys.sleep(0.01)
  

  dt <- round(1000 * diff(t), 1)
  print(dt)
  print(summary(dt))


saveRDS(1:10, 'garb.rds')

loop.test()

代码将产生以下输出(以毫秒为单位的循环时间):

[1]  10.1  10.1  10.2  10.2 275.4  10.2  10.1  10.2  10.2

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.10   10.10   10.20   39.63   10.20  275.40

请注意,大延迟并不总是出现在同一迭代中。

删除代码中的 saveRDS 调用将始终产生一致(接近 10 毫秒)的循环时间。

通过 Rscript 从命令行运行代码可以使用和不使用 saveRDS 行。

【问题讨论】:

今天试用了 RStudio v1.2 预览版。那里也存在这个问题,但程度要小得多。由于 saveRDS,迭代时间不是~275ms,而是~24ms。就此向 RStudio 提交了一张票。 【参考方案1】:

以下是 RStudio 人员的回复:

一种可能性:RStudio 在 R“空闲”期间(即:当 R 调用 R_ProcessEvents 时)做一些后台工作,我认为项目文件索引就是其中之一。 RStudio 会为这些任务注册文件监视器,因此文件的创建可能会导致 RStudio 在后台进行一些重新索引工作。

我确认将 saveRDS() 调用中的保存目录更改为项目目录之外可以解决时间问题。所以我认为这支持文件索引理论。 RStudio v1.2 预览版在较小程度上展示了这种行为,因此空闲处理实现中可能发生了一些变化,但我没有更多信息。 RStudio 的人们打开了一个错误报告来解决这个问题,因此希望该修复程序很快就会提供。

所以现在,一些解决方法是:

    在调用 saveRDS() 后有足够的延迟调用 Sys.sleep() 以允许重新索引操作发生。 将 saveRDS() 指向当前项目目录之外的文件以防止重新编制索引。

【讨论】:

以上是关于与在 RStudio 中使用 saveRDS 相关的时间问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 saveRDS 保存模型但没有足够的内存来读取 RDS?

saveRDS膨胀对象的大小

与在新表达式中解析类型 ID 相关的 gcc 发出错误

RStudio相关

如何解决与在 Windows 10 上安装 dlib 相关的问题?

在共享DLL中使用MFC与在静态库中使用MFC的区别