I'm doing something like this
library(microbenchmark)
library(tidyverse)
f1 = function(n=100) rnorm(n)
f2 = function(n=100, shape1=1, shape2=0.1) rbeta(n, shape1, shape2)
f3 = function(n=100, shape=1) rgamma(n, shape)
maxdif = 1e6
mb = microbenchmark(f1(100), f2(100), f3(100), times=1)
if(max(abs(mb$time - lead(mb$time)), na.rm=TRUE)<maxdif) mb =
microbenchmark(f1(100), f2(100), f3(100), times=10)
mb$time
# [1] 1927396 1876079 1660118 32074 20528 42338 25659 23094 35923 37633
# [11] 16251 39344 27797 38061 13258 12830 38061 13685 13258 23094
# [21] 13686 25232 37633 24377 20528 12830 38061 14113 12402 35495
So far, everything is clear to me and as expected. However, if I enclose it with a function
fComp = function(..., times, maxdif){
mb = microbenchmark(..., times=1)
if(max(abs(mb$time - lead(mb$time)), na.rm=TRUE)<maxdif) mb =
microbenchmark(..., times=times)
mb
}
mb = fComp(f1(100), f2(100), f3(100), times=10, maxdif = 1e6)
mb$time
# [1] 5988 29508 856 429 429 1 1 1 428 0 428 428 0
# [14] 428 1 1 428 0 1 0 1 429 1 1 0 428
# [27] 0 428 1 429
this is something weird going on.
My guess is that it's about passing the ...
parameter. Unfortunately, I don't know how to properly decode ...
to get the desired (as above) effect.
I will be grateful for any hint.
CodePudding user response:
It seems the problem comes from using the ...
twice. I think It's trying to prevent the expressions from being evaluated multiple times which is normally perhaps what you want, but in the case of benchmarking you actually do want to evaluate the same expression multiple times. Here's a work around
fComp = function(..., times, maxdif){
exprs <- match.call(expand.dots = FALSE)$...
mb = microbenchmark(list=exprs, times=1)
if(max(abs(mb$time - lead(mb$time)), na.rm=TRUE)<maxdif) mb =
microbenchmark(list=exprs, times=times)
mb
}
We use match.call
to get the unevaluated expressions passed in the ...
. We then pass those parameters to microbenchmark()
via the list=
parameter rather than using ...
. This seems to avoid that optimization.
This method also preserved the expression names in the output
fComp(f1(100), f2(100), f3(100), times=10, maxdif = 1e6)
Unit: microseconds
expr min lq mean median uq max neval
f1(100) 8.4 8.7 9.29 9.05 9.6 11.2 10
f2(100) 25.1 25.7 28.40 25.95 27.5 46.9 10
f3(100) 13.5 16.3 18.09 17.85 20.3 23.5 10
CodePudding user response:
One way is to change the order of ...
as the last argument and it works
fComp = function(times, maxdif, ...){
mb = microbenchmark(times=1, ...)
if(max(abs(mb$time - lead(mb$time)), na.rm=TRUE)<maxdif) mb =
microbenchmark(times=times, ...)
mb
}
-testing
fComp(times=10, maxdif = 1e6, f1(100), f2(100), f3(100))
Unit: microseconds
expr min lq mean median uq max neval
..1 1957.235 1957.235 1957.235 1957.235 1957.235 1957.235 1
..2 101.801 101.801 101.801 101.801 101.801 101.801 1
..3 170.926 170.926 170.926 170.926 170.926 170.926 1