【问题标题】:Measuring function execution time in R在 R 中测量函数执行时间
【发布时间】:2011-09-09 20:54:03
【问题描述】:

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

【问题讨论】:

  • 我想你已经想到了 proc.time,因为 system.time 是你需要的。
  • 对于更大的功能,Rprof 很好。它提供了代码块/函数中所有进程的概要文件。
  • 新 R 用户通过 google 找到这个问题:require(microbenchmark) 现在(从几年前开始)是社区标准的计时方式。 times <- microbenchmark( lm(y~x), glm(y~x), times=1e3); example(microbenchmark)。这会对lmglm 进行超过1000 次尝试的统计比较,而不是system.time 仅测试一次。
  • 使用res <- microbenchmark(your code1,your code2) 然后print(res) 查看表格或ggplot2::autoplot(res) 查看箱线图! ref

标签: r time profiling


【解决方案1】:

内置函数system.time()会做到这一点。

像这样使用:system.time(result <- myfunction(with, arguments))

【讨论】:

  • 重要的是要知道system.time() 有一个参数gcFirst,默认情况下是TRUE。一方面,这使测量更具可重复性,但可能会产生显着的总运行时间开销(当然,这是未测量的)。
  • 这是用什么单位测量的?例如,我刚刚运行 system.time(result <- myfunction(with, arguments)) 并得到 187.564 作为输出 - 是在几秒钟内还是什么?
  • 对于使用system.time的人,请阅读以下内容以了解一些警告:“object not found” and “unexpected symbol” errors when timing R code with system.time()
  • @zsad512 我有理由确定那些是seconds
【解决方案2】:

测量执行时间的更好方法是使用rbenchmark 包。这个包(很容易)允许您指定复制测试的次数以及相对基准应该是多少次。

另请参阅stats.stackexchange 上的相关问题

【讨论】:

  • Microbenchmark 更好,因为它使用了更高精度的计时函数。
  • @hadley 但是 rbenchmark 在比较的情况下更加用户友好。对我来说,微基准是升级的 system.time。 rmicrobenchmark 是我们需要的 :)
  • microbenchmark 的维护者反应灵敏 - 我敢打赌他会添加你需要的任何东西。
【解决方案3】:

如果您愿意,可以使用 MATLAB 风格的 tic-toc 函数。请参阅其他 SO 问题

Stopwatch function in R

【讨论】:

  • 正要添加proc.time()……我更喜欢这个可爱的名字。 =)
【解决方案4】:

正如安德烈所说,system.time() 工作正常。对于简短的函数,我更喜欢将replicate() 放入其中:

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

【讨论】:

  • 你最好使用 microbenchmark 包,因为它不包括计时中的复制开销。
【解决方案5】:

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

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

与上面的答案相比,这不是最优雅的方式,但绝对是一种方式。

【讨论】:

  • 这更节省内存,然后是 system.time(),它有效地复制了它的参数。当您处理的数据几乎不适合您的 RAM 时,这一点很重要。
  • 对于使用Sys.time的人,请阅读以下内容以了解一些警告:Timing R code with Sys.time()
  • system.time() 对我来说更快。我认为应该接受system.time() 的答案!
  • 这是我了解在多个内核上并行完成长时间计算所需时间的首选方法。在这种情况下,通过此调用测量的挂钟时间足够准确,因为计算机将比执行其他任何操作更忙于计算所有内核,并且计算需要几分钟或几小时才能完成。这是一个非常具体的用例,但值得一提。
  • 对于那些喜欢单线的人:s=Sys.time(); &lt;code here&gt; ; Sys.time()-s;。这将打印时差以及您的代码可能产生的任何输出。
【解决方案6】:

还有proc.time()

您可以使用与Sys.time 相同的方式,但它会为您提供与system.time 相似的结果。

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

使用的主要区别

system.time({ #your function here })

proc.time() 方法仍然执行您的功能,而不仅仅是测量时间... 顺便说一句,我喜欢在system.time 里面使用{},这样你就可以放一组东西了...

【讨论】:

    【解决方案7】:

    “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
    

    【讨论】:

      【解决方案8】:

      虽然其他解决方案对单个函数有用,但我推荐以下更通用和有效的代码:

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

      【讨论】:

      • 直到现在我才知道 Rprof,它确实很棒!加上它带有基本 R,所以不需要像 microbenchmarkprofvis 这样的额外包。
      • 我想知道 rprof 是否也可以可视化,例如,如果我们想为它分析的每个项目绘制时间?
      • @ZawirAmin 有办法,用Rstudio >> profile menu
      【解决方案9】:

      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 ns。

      【讨论】:

        【解决方案10】:

        另一个简单但非常强大的方法是使用包profvis。它不仅测量代码的执行时间,还让您深入了解您执行的每个函数。它也可以用于 Shiny。

        library(profvis)
        
        profvis({
          #your code here
        })
        

        点击here查看一些示例。

        【讨论】:

          【解决方案11】:

          您可以使用Sys.time()。但是,当您在表格或 csv 文件中记录时差时,您不能简单地说end - start。相反,您应该定义单位:

          f_name <- function (args*){
          start <- Sys.time()
          """ You codes here """
          end <- Sys.time()
          total_time <- as.numeric (end - start, units = "mins") # or secs ... 
          }
          

          然后你可以使用total_time,它的格式是正确的。

          【讨论】:

            【解决方案12】:

            bench::mark() from package bench 用于对一个或一系列表达式进行基准测试,我们认为它比替代方案具有许多优势。 source

            用途:

            bench::mark(log10(5))
            #> # A tibble: 1 × 6
            #>   expression      min   median `itr/sec` mem_alloc `gc/sec`
            #>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
            #> 1 log10(5)      212ns    274ns  2334086.        0B        0
            

            reprex package (v2.0.1) 于 2021-08-18 创建

            【讨论】:

              【解决方案13】:

              从上面所有的答案中编译,我想出了使用这些简化的 tic toc 函数

              tic <- function(){ start.time <<- Sys.time() }
              toc <- function(){ round(Sys.time() - start.time) }
              

              用作:

              tic()
              Sys.sleep(3)
              toc()
              

              以及打印的内容:

              时差3秒

              【讨论】:

                猜你喜欢
                • 2017-01-09
                • 2023-03-09
                • 2016-01-28
                相关资源
                最近更新 更多