由工厂功能构造的“ microbenchmark”功能

廖里

我有一个根据某些特定参数构造另一个函数的函数:

factory <- function(param) {
    # some long computation…
    cached.matrix = rnorm(param)

    # return function that uses cached data
    function(other) {
        cached.matrix * cached.matrix + other
    }
}

现在,我想factory使用该microbenchmark由函数生成的函数针对各种参数进行基准测试microbenchmark函数接受一个表达式,而不是一个函数,经过一些实验,我注意到以下与之共舞do.callcall似乎起作用的方法:

params <- seq(5, 100, 5)
list.of.expressions <- sapply(
    params,
    function(param) call('do.call', factory(param), list(7)))
names(list.of.expressions) <- sprintf("f%04d", params)
mb.results <- microbenchmark(list=list.of.expressions, times=10)

有没有比这样更简单的方法来收集参数化的基准测试结果call('do.call', …)

托尼托诺夫

我将展示另一条可能的路线。您要做的是构造未求值的表达式,而我将把microbenchmark调用包装到一个函数中并outer用于产生所需的细分。

我隐式地假设您要遍历两个维度(在您的示例中,paramother)。我建立了自己的函数工厂:

factory <- function(param) {
  x <- rnorm(param)
  function(mat) {
    t(x) %*% mat %*% x
  }
}

现在,我要遍历parammat为了使其更加有趣,请mat依靠param某种方式。如果不是这种情况,请忽略mat作为函数:它可以是向量。

params <- seq(10, 50, 10)
mat1 <- function(param) {diag(param)}
mat2 <- function(param) {matrix(runif(param^2), param)}

这是将转到的函数outer,以及调用本身:

test_factory_med <- Vectorize(function(param, matf) {
         summary(microbenchmark(factory(param)(matf(param))))$median
})
median_tests <- outer(params, c(mat1, mat2), 
                      FUN = function(p, m) test_factory_med(p, m))

colnames(median_tests) <- c("mat1", "mat2")
rownames(median_tests) <- params
median_tests
#      mat1     mat2
#10 15.3150  22.6720
#20 18.6180  36.6355
#30 22.2220  57.9560
#40 27.3265  88.5860
#50 32.7320 129.1250

您可以microbenchmark通过返回完整的信息集来保留其中的完整信息(使用我最近提出的问题中的列表包装技巧):

test_factory_all <- Vectorize(function(param, matf) {
  list(
    list(param = param, 
         matf = mat,
         microbenchmark(factory(param)(matf(param)))))
})

all_tests <- outer(params, c(mat1, mat2), 
                   FUN = function(p, m) test_factory_all(p, m))
all_tests[1, 1]

#[[1]]
#[[1]]$param
#[1] 10
#
#[[1]]$matf
#function (param) 
#{
#    diag(param)
#}
#
#[[1]][[3]]
#Unit: microseconds
#                        expr    min     lq     mean median     uq    max neval
# factory(param)(matf(param)) 14.414 15.315 17.17081 15.916 16.516 88.586   100

编辑:针对下面的评论,这是仅测量从工厂发出的函数调用的方法。

# exclude costs for running factory
test_factory_med1 <- Vectorize(function(param, matf) {
         f <- factory(param)
         summary(microbenchmark(f(matf(param))))$median
})

# exclude costs for both running factory and constructing parameter
test_factory_med2 <- Vectorize(function(param, matf) {
         f <- factory(param)
         m <- matf(param)
         summary(microbenchmark(f(m)))$median
})

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章