清楚地比较不同方法在R中具有相同目标的性能?

时间:2015-10-07 09:58:10

标签: r performance benchmarking

R中,我如何能够将不同的解决方案与同一个问题进行干净的比较,即“公平”。他们每个人之间? 可以在其他人改变后者的性能之前运行资源消耗的解决方案吗? 怎么可以清洁'每次测试之间的机器状态?

假设我想计算矩阵的平均值,我可以用简单或复杂的方式来做:

set.seed(9)
N = 1e7
ncol = 1e3
myT = matrix(runif(N), ncol = ncol)

func1 <- function(mat) {
  colMeans(mat)
}

func2 <- function(mat) {
  apply(mat, 2, function(x) sum(x)/length(x))
}

func3 <- function(mat) {
  nrows = c()
  for (i in 1:nrow(mat)) {
    nrows = c(nrows, 1) # yes, this is very stupid ;-)
  }
  colSums(mat) / sum(nrows)
}


system.time( replicate(1, t1 <- func1(myT)))
# user  system elapsed 
# 0.012   0.000   0.011 
system.time( replicate(1, t2 <- func2(myT)))
# user  system elapsed 
# 0.136   0.036   0.170
system.time( replicate(1, t3 <- func3(myT)))
# user  system elapsed 
# 0.140   0.032   0.170

执行system.time()执行几次可以为同一个测试提供不同的结果(可能会改变结论)。我注意到更复杂,资源消耗的解决方案尤其如此,而最干净的解决方案往往具有更一致的执行时间 - 这是什么原因?如何避免同一个表达式的执行之间发生重大变化,以及如何防止它们相互干扰?

测试之间对gc()的调用是否有用,是否足够?

我也知道microbenchmark套餐,但我正在寻找更多内容&#39;手册&#39;为了理解会发生什么。

我正在与RStudio合作,以防万一......

1 个答案:

答案 0 :(得分:1)

microbenchmark就是为此而设计的。 system.time()并不详细

set.seed(9)
N = 1e5
ncol = 1e3
myT = matrix(runif(N), ncol = ncol)

library(microbenchmark)
microbenchmark(
  colmeans = colMeans(myT),
  wrong_apply = apply(myT, 2, function(x) sum(x)/length(x)), # wrong in case of NA
  correct_apply = apply(myT, 2, mean, na.rm = TRUE), # correct in case of NA
  stupid = {
    nrows = c()
    for (i in 1:nrow(myT)) {
      nrows = c(nrows, 1) # yes, this is very stupid ;-)
    }
    colSums(myT) / sum(nrows)
  }
)

输出

Unit: microseconds
          expr      min       lq       mean   median       uq       max neval cld
      colmeans   87.235   92.367   96.44175   95.787   98.781   129.142   100 a  
   wrong_apply 3004.886 3071.595 3483.02090 3166.739 3267.445 18707.947   100  b 
 correct_apply 7595.387 7895.148 8850.87886 8106.179 8461.745 13928.438   100   c
        stupid  144.109  156.510  166.15237  163.351  171.690   255.290   100 a