Out of 这个帖子 https://stackoverflow.com/questions/53971364/split-a-vector-and-summing-values/53971606#53971606在对各种解决方案进行基准测试时引发了讨论。考虑下面的代码
# global environment is empty - new session just started
# set up
set.seed(20181231)
n <- sample(10^3:10^4,10^3)
for_loop <- function(n) {
out <- integer(length(n))
for(k in 1:length(out)) {
if((k %% 2) == 0){
out[k] <- 0L
next
}
out[k] <- 1L
next
}
out
}
# benchmarking
res <- microbenchmark::microbenchmark(
for_loop = {
out <- integer(length(n))
for(k in 1:length(out)) {
if((k %% 2) == 0){
out[k] <- 0L
next
}
out[k] <- 1L
next
}
out
},
for_loop(n),
times = 10^4
)
以下是完全相同的循环的基准测试结果,一个循环包含在函数中,另一个则没有
# Unit: microseconds
# expr min lq mean median uq max neval cld
# for_loop 3216.773 3615.360 4120.3772 3759.771 4261.377 34388.95 10000 b
# for_loop(n) 162.280 180.149 225.8061 190.724 211.875 26991.58 10000 a
ggplot2::autoplot(res)
可以看出,效率上存在巨大差异。这背后的根本原因是什么?
需要明确的是,问题不是关于上述代码解决的任务(可以更优雅地完成),而仅仅是关于常规循环和包装在函数内的循环之间的效率差异。
解释是函数是“即时”编译的,而解释的代码则不是。看?compiler::enableJIT
以获得描述。
如果您想演示差异,请运行
compiler::enableJIT(0)
在您的任何代码之前(包括的创建for_loop
功能)。这会禁用该会话其余部分的 JIT 编译。那么两组代码的时序将更加相似。
您必须在创建之前执行此操作for_loop
函数,因为一旦它被 JIT 编译器编译,无论 JIT 是否启用,它都会保持编译状态。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)