【问题标题】:Return system.time by default默认返回system.time
【发布时间】:2012-12-01 17:45:18
【问题描述】:

我必须对大数据集进行大量数据操作(主要使用 data.table、RStudio)。我想监控每个步骤的运行时间,而不需要在每个步骤上显式调用 system.time()。

是否有一个包或一种简单的方法可以在每个步骤中默认显示运行时间?

谢谢。

【问题讨论】:

  • 感谢 agstudy。我知道 rbenchmark,但这不是我需要的。我想要一个“副作用”,为每个 R 函数调用产生运行时间。我不确定是否有可能
  • 这是一个很好的问题。更重要的是,因为我发现即使您在一个大型项目的每个步骤中使用system.time,其中包含许多source 调用和函数,源文件和内部函数中的system.time 请求也会被忽略(也许有一些解决这个问题的方法,比如print,但我还没有确认,这是我针对这个确切主题的潜在问题的问题前研究的一部分。

标签: r


【解决方案1】:

这并不完全符合您的要求,但我已经写了 time_file (https://gist.github.com/4183595),其中 source()s 是一个 R 文件,并运行代码,然后重写文件,插入包含每个顶级语句运行时间的 cmets。

time_file() 转这个:

{
  load_all("~/documents/plyr/plyr")
  load_all("~/documents/plyr/dplyr")
  library(data.table)
  data("baseball", package = "plyr")
  vars <- list(n = quote(length(id)), m = quote(n + 1))
}

# Baseline case: use ddply
a <- ddply(baseball, "id", summarise, n = length(id))

# New summary method: ~20x faster
b <- summarise_by(baseball, group("id"), vars)

# But still not as fast as specialised count, which is basically id + tabulate
# so maybe able to eke out a little more with a C loop ?
count(baseball, "id")

进入这个:

{
  load_all("~/documents/plyr/plyr")
  load_all("~/documents/plyr/dplyr")
  library(data.table)
  data("baseball", package = "plyr")
  vars <- list(n = quote(length(id)), m = quote(n + 1))
}

# Baseline case: use ddply
a <- ddply(baseball, "id", summarise, n = length(id))
#:    user  system elapsed
#:   0.451   0.003   0.453

# New summary method: ~20x faster
b <- summarise_by(baseball, group("id"), vars)
#:    user  system elapsed
#:   0.029   0.000   0.029

# But still not as fast as specialised count, which is basically id + tabulate
# so maybe able to eke out a little more with a C loop ?
count(baseball, "id")
#:    user  system elapsed
#:   0.008   0.000   0.008

它不会对顶级 { 块内的代码进行计时,因此您可以选择不对您不感兴趣的内容计时。

我认为无论如何都不会自动添加计时作为顶级效果而不以某种方式修改您运行代码的方式 - 即使用类似 time_file 而不是 source

您可能想知道每个顶级操作的计时对代码的整体速度有何影响。嗯,这很容易用微基准来回答;)

library(microbenchmark)
microbenchmark(
  runif(1e4), 
  system.time(runif(1e4)),
  system.time(runif(1e4), gc = FALSE)
)

因此,时间增加的开销相对较小(我的计算机上为 20µs),但默认 gc 每次调用增加约 27 ms。因此,除非您有数千个顶级调用,否则您不太可能看到太大的影响。

【讨论】:

  • 我想知道用 每个 函数调用检查时间是否会减慢整个过程的速度。
  • @DWin 微基准测试添加 - 每个顶级函数调用大约 20 毫秒,这不太可能对大多数脚本产生明显影响。
  • @Hadley R 有等效的 python 装饰器吗?我问这个是因为使用这个功能可以提高你的时间分析的清晰度。
  • @AdamNYC 如果你想要互动,你可以在evaluate 之上构建一些东西
  • @DWin load_all 来自 devtools,但是除非您碰巧将我的软件包的开发版本安装在与我完全相同的位置,否则该示例对您不起作用;)
【解决方案2】:

对于这个额外的答案,我必须完全归功于Freenode#R IRC 频道的@jbecker,但对我来说,解决方案在这里:http://adv-r.had.co.nz/Profiling.html

这里只是一点点的味道:

“要了解性能,您可以使用分析器。有许多不同类型的分析器。R 使用一种相当简单的类型,称为采样或统计分析器。采样分析器每隔几毫秒就会停止执行代码并记录当前正在执行的函数(以及调用该函数的函数,等等)。例如,考虑下面的 f():"

library(lineprof)
f <- function() {
  pause(0.1)
  g()
  h()
}
g <- function() {
  pause(0.1)
  h()
}
h <- function() {
  pause(0.1)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 2013-01-19
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多