在R中测量函数执行时间

350

在R语言中,是否有一种标准化的方法来测量函数的执行时间?

显然,我可以在执行前后使用system.time,然后取这两个时间的差值,但我想知道是否有一些标准化的方法或函数(不想重新发明轮子)。


我记得曾经使用过类似于下面的内容:

somesysfunction("myfunction(with,arguments)")
> Start time : 2001-01-01 00:00:00  # output of somesysfunction
> "Result" "of" "myfunction"        # output of myfunction
> End time : 2001-01-01 00:00:10    # output of somesysfunction
> Total Execution time : 10 seconds # output of somesysfunction

2
我认为你想到了 proc.time,因为你需要的是 system.time - Marek
2
对于较大的函数,Rprof 是一个不错的选择。它可以提供代码块/函数中所有进程的概要信息。 - Rich Scriven
51
新的 R 用户通过谷歌来到这个问题页面:require(microbenchmark) 现在(自几年前起)是衡量效率的社区标准方法。 times <- microbenchmark( lm(y~x), glm(y~x), times=1e3); example(microbenchmark) 这将对 lmglm 进行 1000 次统计比较,而不是仅进行一次 system.time 测试。 - isomorphismes
使用 res <- microbenchmark(你的代码1, 你的代码2),然后使用 print(res) 查看表格或者使用 ggplot2::autoplot(res) 查看箱线图!参考链接 - Travis
15个回答

318

另一种可能的做法是使用Sys.time():

start.time <- Sys.time()
...Relevent codes...
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

虽然相比上面的答案,这不是最优雅的方法,但绝对是一种可行的方法。


17
这个方法比system.time()更节省内存,因为它有效地避免了参数的复制。这在处理数据大小接近你的内存容量时非常重要。 - Adam Ryczkowski
4
使用Sys.time的人,请阅读一些注意事项:使用Sys.time()计时R代码 - Zheyuan Li
1
system.time() 对我来说更快。我认为 system.time() 的答案应该被接受! - Gwang-Jin Kim
这是我首选的方法,用于了解在多个核心上并行进行的长时间计算所需的时间。在这种情况下,通过此调用测量的挂钟时间足够准确,因为计算机将忙于所有核心的计算而不是做其他任何事情,并且计算需要几分钟或几小时才能完成。这是一个非常特定的用例,但值得一提。 - Pablo Adames
2
对于那些喜欢单行代码的人来说: s=Sys.time(); <code here> ; Sys.time()-s;。这将打印时间差异,以及您的代码可能产生的任何输出。 - Cole

219
内置函数system.time() 可以实现此功能。
用法如下:system.time(result <- myfunction(带有, 参数))

1
需要知道的是,system.time() 函数有一个名为 gcFirst 的参数,默认值为 TRUE。一方面,这使得测量结果更具可重复性,但另一方面也可能会导致总运行时间显著增加(当然,这部分时间不会被计算在内)。 - jakob-r
2
这是用什么单位来衡量的?例如,我刚刚运行了 system.time(result <- myfunction(with, arguments)) 并得到了 187.564 的输出结果 - 这是以秒为单位还是其他什么单位? - zsad512
对于使用 system.time 的人,请阅读以下注意事项:“object not found” and “unexpected symbol” errors when timing R code with system.time() - Zheyuan Li
@zsad512 我相当确定那些是秒数 - Tapper

64

正如Andrie所说,system.time()很好用。对于短函数,我更喜欢将replicate()放在其中:

system.time( replicate(10000, myfunction(with,arguments) ) )

31
最好使用microbenchmark包,因为它在计时中不包括replicate的开销。 - hadley

56

microbenchmark 是一个轻量级(约50KB)的包,在 R 中用于对多个表达式和函数进行基准测试的标准方式:

microbenchmark(myfunction(with,arguments))
例如:
> microbenchmark::microbenchmark(log10(5), log(5)/log(10), times = 10000)
Unit: nanoseconds
           expr min lq    mean median uq   max neval cld
       log10(5)   0  0 25.5738      0  1 10265 10000   a
 log(5)/log(10)   0  0 28.1838      0  1 10265 10000

这两个表达式都被评估了10000次,平均执行时间约为25-30纳秒。


41

一种稍微更好的测量执行时间的方法是使用rbenchmark包。该包(轻松地)允许您指定测试应重复多少次以及相对基准应该是什么。

另请参阅相关问题:stats.stackexchange


6
微基准测试甚至更好,因为它使用更高精度的计时函数。 - hadley
4
@hadley,但是在比较方面,rbenchmark更加用户友好。对我来说,microbenchmark是升级版的system.time。rmicrobenchmark是我们所需要的 :) - Marek
3
microbenchmark 的维护者非常积极,我敢打赌他会添加你需要的任何内容。 - hadley

41

还有 proc.time()

你可以像使用Sys.time一样使用它,但它会给出与system.time类似的结果。

ptm <- proc.time()
#your function here
proc.time() - ptm

使用的主要区别在于

system.time({ #your function here })

这意味着proc.time()方法仍然会执行您的函数,而不仅仅是测量时间...顺便说一句,我喜欢在{}内使用system.time,这样您就可以放置一组内容...


33

“tictoc”软件包提供了一种非常简单的测量执行时间的方法。文档位于:https://cran.fhcrc.org/web/packages/tictoc/tictoc.pdf

install.packages("tictoc")
require(tictoc)
tic()
rnorm(1000,0,1)
toc()

要将经过的时间保存到变量中,可以这样做:

install.packages("tictoc")
require(tictoc)
tic()
rnorm(1000,0,1)
exectime <- toc()
exectime <- exectime$toc - exectime$tic

22

虽然其他解决方案对于单一功能很有用,但我推荐以下代码片段,因为它更加通用和有效:

Rprof(tf <- "log.log", memory.profiling = TRUE)
# the code you want to profile must be in between
Rprof (NULL) ; print(summaryRprof(tf))

2
直到现在我才知道Rprof,它确实很棒!而且它是基于base R的,所以不需要额外的包,如microbenchmarkprofvis - Simon C.
我想知道能否将rprof可视化,比如说如果我们想绘制每个项目的时间进行分析? - Zawir Amin
@ZawirAmin 有一种方法,只需使用Rstudio >> 配置文件菜单。 - TPArrow

15

另一个简单而非常强大的方法是使用 profvis 包。它不仅可以测量代码的执行时间,而且还可以为您执行的每个函数提供详细信息。它也可以用于Shiny。

library(profvis)

profvis({
  #your code here
})

点击此处以查看一些示例。


14
您可以使用类似MATLAB的tic-toc函数,如果您喜欢的话。请参考这个其他的SO问题。
在R中的秒表功能。请参阅此Stack Overflow问题

我本来要添加 proc.time() 的……但我更喜欢这个可爱的名字。=) - isomorphismes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接