R microbenchmark:如何将相同的参数传递给评估函数?
R microbenchmark: How to pass same argument to evaluated functions?
我想评估使用不同文件类型(geotiff、二进制)或对象(RasterBrick、RasterStack)从栅格时间序列中提取数据的时间。我创建了一个函数,该函数将从栅格对象的随机点提取时间序列,然后使用微基准对其进行测试。
例如:
# read a random point from a raster stack
sample_raster <- function(stack) {
poi <- sample(ncell(stack), 1)
raster::extract(stack, poi)
}
# opening the data using different methods
data_stack <- stack(list.files(pattern = '3B.*tif'))
data_brick <- brick('gpm_multiband.tif')
bench <- microbenchmark(
sample_stack = sample_raster(data_stack),
sample_brick = sample_raster(data_brick),
times = 10
)
boxplot(bench)
# this fails because sampled point is different
bench <- microbenchmark(
sample_stack = sample_raster(data_stack),
sample_brick = sample_raster(data_brick),
times = 10,
check = 'equal'
)
我包含了我的数据集样本 here
有了这个,我可以看到 RasterBrick 上的采样比堆栈快(R Raster 手册也这么说——很好)。问题是我在每个评估表达式的不同点进行采样。所以我无法检查结果是否相同。我想做的是在两个对象的相同位置 (poi) 进行采样。但是每次迭代的位置都不同。我尝试在 microbenchmark 中使用 setup 选项,但据我所知, setup 在每个函数定时之前进行评估,而不是每次迭代一次.因此使用设置生成随机 poi 将不起作用。
是否可以将相同的参数传递给在 microbenchmark 中评估的函数?
结果
解决方案使用microbenchmark
按照建议(并在下面解释),我尝试了 bench
包和 press
调用。但出于某种原因,它比在每个 microbenchmark
迭代中设置相同的种子要慢,正如 mnist 所建议的那样。所以我最终回到了 microbenchmark
。这是我正在使用的代码:
library(microbenchmark)
library(raster)
annual_brick <- raster::brick('data/gpm_tif_annual/gpm_2016.tif')
annual_stack <- raster::stack('data/gpm_tif_annual/gpm_2016.tif')
x <- 0
y <- 0
bm <- microbenchmark(
ext = {
x <- x + 1
set.seed(x)
poi = sample(raster_size, 1)
raster::extract(annual_brick, poi)
},
slc = {
y <- y + 1
set.seed(y)
poi = sample(raster_size, 1)
raster::extract(annual_stack, poi)
},
check = 'equal'
)
解决方案使用bench::press
为了完整起见,我就是这样做的,使用 bench::press
。在此过程中,我还将用于选择随机单元格的代码与点采样函数分开。所以我只能对代码的点采样部分进行计时。这是我的做法:
library(bench)
library(raster)
annual_brick <- raster::brick('data/gpm_tif_annual/gpm_2016.tif')
annual_stack <- raster::stack('data/gpm_tif_annual/gpm_2016.tif')
bm <- bench::press(
pois = sample(ncell(annual_brick), 10),
mark(
iterations = 1,
sample_brick = raster::extract(annual_brick, pois),
sample_stack = raster::extract(annual_stack, pois)
)
)
如果我没理解错的话,OP 有两个 要求:
- 在对两个表达式进行计时时,应采样相同的数据点,以检查结果是否相同。
- 此外,两个表达式的时序将针对采样的不同数据点重复。
使用相同的随机数
如 所建议,set.seed()
可用于设置 R 的随机数生成器的种子值。如果使用相同的参数,则生成的随机数顺序相同
可以修改 sample_raster()
以确保随机数生成器将为 each 调用初始化。
sample_raster <- function(stack) {
set.seed(1L)
poi <- sample(ncell(stack), 1)
raster::extract(stack, poi)
}
这将满足要求 1 但不满足要求 2,因为相同的数据样本将用于所有重复。
重复的随机数不同
OP 要求:
Is it possible to pass the same argument to the functions being
evaluated in microbenchmark?
一种可能性是使用 for
或 lapply()
循环种子值序列,如对类似 .
的回答中所建议的那样
在这种情况下,我建议使用 bench
包进行基准测试。它有一个 press()
函数,可在参数网格中运行 bench::mark()
。
为此,sample_raster()
得到第二个参数:
sample_raster <- function(stack, seed) {
set.seed(seed)
poi <- sample(ncell(stack), 1L)
# cat(substitute(f), s, poi, "\n") # just to check, NOT to use for timings
raster::extract(stack, poi)
}
按照矢量 seed_vec
中给定的不同种子执行计时。
library(bench)
bm <- press(
seed_vec = 1:10,
mark(
iterations = 1L,
sample_stack = sample_raster(data_stack, seed_vec),
sample_brick = sample_raster(data_brick, seed_vec)
)
)
请注意,seed_vec
的长度现在决定了 不同 poi
的重复次数。 mark()
的 iterations
参数指定 same seed / poi
.
的计时重复频率
可以使用
绘制结果
library(ggplot2)
autoplot(bm)
或使用
总结
library(dplyr)
bm %>%
group_by(expression = expression %>% as.character()) %>%
summarise(median = median(median), n_itr = n())
我的方法是为 microbenachmark 中的每个选项设置相同的席位,但在每次函数调用之前更改它们。查看输出以及相同的座位最终如何用于两个调用
x <- 0
y <- 0
microbenchmark::microbenchmark(
"checasdk" = {
# increase seat value by 1
x <- x + 1
print(paste("1", x))
set.seed(x)},
"check2" = {
y <- y + 1
print(paste("2", y))
set.seed(y)
}
)
我想评估使用不同文件类型(geotiff、二进制)或对象(RasterBrick、RasterStack)从栅格时间序列中提取数据的时间。我创建了一个函数,该函数将从栅格对象的随机点提取时间序列,然后使用微基准对其进行测试。
例如:
# read a random point from a raster stack
sample_raster <- function(stack) {
poi <- sample(ncell(stack), 1)
raster::extract(stack, poi)
}
# opening the data using different methods
data_stack <- stack(list.files(pattern = '3B.*tif'))
data_brick <- brick('gpm_multiband.tif')
bench <- microbenchmark(
sample_stack = sample_raster(data_stack),
sample_brick = sample_raster(data_brick),
times = 10
)
boxplot(bench)
# this fails because sampled point is different
bench <- microbenchmark(
sample_stack = sample_raster(data_stack),
sample_brick = sample_raster(data_brick),
times = 10,
check = 'equal'
)
我包含了我的数据集样本 here
有了这个,我可以看到 RasterBrick 上的采样比堆栈快(R Raster 手册也这么说——很好)。问题是我在每个评估表达式的不同点进行采样。所以我无法检查结果是否相同。我想做的是在两个对象的相同位置 (poi) 进行采样。但是每次迭代的位置都不同。我尝试在 microbenchmark 中使用 setup 选项,但据我所知, setup 在每个函数定时之前进行评估,而不是每次迭代一次.因此使用设置生成随机 poi 将不起作用。
是否可以将相同的参数传递给在 microbenchmark 中评估的函数?
结果
解决方案使用microbenchmark
按照建议(并在下面解释),我尝试了 bench
包和 press
调用。但出于某种原因,它比在每个 microbenchmark
迭代中设置相同的种子要慢,正如 mnist 所建议的那样。所以我最终回到了 microbenchmark
。这是我正在使用的代码:
library(microbenchmark)
library(raster)
annual_brick <- raster::brick('data/gpm_tif_annual/gpm_2016.tif')
annual_stack <- raster::stack('data/gpm_tif_annual/gpm_2016.tif')
x <- 0
y <- 0
bm <- microbenchmark(
ext = {
x <- x + 1
set.seed(x)
poi = sample(raster_size, 1)
raster::extract(annual_brick, poi)
},
slc = {
y <- y + 1
set.seed(y)
poi = sample(raster_size, 1)
raster::extract(annual_stack, poi)
},
check = 'equal'
)
解决方案使用bench::press
为了完整起见,我就是这样做的,使用 bench::press
。在此过程中,我还将用于选择随机单元格的代码与点采样函数分开。所以我只能对代码的点采样部分进行计时。这是我的做法:
library(bench)
library(raster)
annual_brick <- raster::brick('data/gpm_tif_annual/gpm_2016.tif')
annual_stack <- raster::stack('data/gpm_tif_annual/gpm_2016.tif')
bm <- bench::press(
pois = sample(ncell(annual_brick), 10),
mark(
iterations = 1,
sample_brick = raster::extract(annual_brick, pois),
sample_stack = raster::extract(annual_stack, pois)
)
)
如果我没理解错的话,OP 有两个 要求:
- 在对两个表达式进行计时时,应采样相同的数据点,以检查结果是否相同。
- 此外,两个表达式的时序将针对采样的不同数据点重复。
使用相同的随机数
如 set.seed()
可用于设置 R 的随机数生成器的种子值。如果使用相同的参数,则生成的随机数顺序相同
sample_raster()
以确保随机数生成器将为 each 调用初始化。
sample_raster <- function(stack) {
set.seed(1L)
poi <- sample(ncell(stack), 1)
raster::extract(stack, poi)
}
这将满足要求 1 但不满足要求 2,因为相同的数据样本将用于所有重复。
重复的随机数不同
OP 要求:
Is it possible to pass the same argument to the functions being evaluated in microbenchmark?
一种可能性是使用 for
或 lapply()
循环种子值序列,如对类似
在这种情况下,我建议使用 bench
包进行基准测试。它有一个 press()
函数,可在参数网格中运行 bench::mark()
。
为此,sample_raster()
得到第二个参数:
sample_raster <- function(stack, seed) {
set.seed(seed)
poi <- sample(ncell(stack), 1L)
# cat(substitute(f), s, poi, "\n") # just to check, NOT to use for timings
raster::extract(stack, poi)
}
按照矢量 seed_vec
中给定的不同种子执行计时。
library(bench)
bm <- press(
seed_vec = 1:10,
mark(
iterations = 1L,
sample_stack = sample_raster(data_stack, seed_vec),
sample_brick = sample_raster(data_brick, seed_vec)
)
)
请注意,seed_vec
的长度现在决定了 不同 poi
的重复次数。 mark()
的 iterations
参数指定 same seed / poi
.
可以使用
绘制结果library(ggplot2)
autoplot(bm)
或使用
总结library(dplyr)
bm %>%
group_by(expression = expression %>% as.character()) %>%
summarise(median = median(median), n_itr = n())
我的方法是为 microbenachmark 中的每个选项设置相同的席位,但在每次函数调用之前更改它们。查看输出以及相同的座位最终如何用于两个调用
x <- 0
y <- 0
microbenchmark::microbenchmark(
"checasdk" = {
# increase seat value by 1
x <- x + 1
print(paste("1", x))
set.seed(x)},
"check2" = {
y <- y + 1
print(paste("2", y))
set.seed(y)
}
)