我目前正在处理一个问题,我执行多个函数是迭代执行的。每次迭代时,输入都取决于前一次运行的结果。目前我使用了'for循环',但为了加快运行速度,我有兴趣用apply函数替换这个循环。
apply函数通常不会考虑全局环境参数的更改。但是,全局变量可以直接更改。因此,以下代码是相同的。
a <- 1
sapply(seq_len(5), function(x){
a <<- a + 1
})
a <- 1
for(i in seq_len(5)){
a <- a + 1
}
从for循环更改为直接更改全局变量的apply函数会导致计算时间减少吗?
答案 0 :(得分:0)
不,它不会更快。
我们可以使用microbenchmark
包进行比较:
n = 1e5
microbenchmark::microbenchmark(sapply = {
a <- 1
sapply(seq_len(n), function(x) {
a <<- a + 1
})
},
forloop = {
a <- 1
for (i in seq_len(n)) {
a <- a + 1
}
})
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# sapply 55.081023 67.740821 86.924793 78.312672 100.079169 424.137078 100 b
# forloop 3.950579 4.267804 4.666161 4.492243 4.764634 8.714735 100 a
平均而言,sapply
版本在长度为100k的输入上比for
循环版本慢20倍。当我尝试使用<<-
运行for循环时,全局分配显然很昂贵,然后差异接近3倍。
但这种差异基本上没有意义。如果我们看每次迭代 ,则每次迭代需要0.078秒/ 100k次迭代= 780纳秒。 for循环每次迭代需要40纳秒。你的实际代码有希望做一些比单个添加更有趣的东西,所以它可能需要几微秒,或者更多可能是几毫秒,甚至几秒!每次迭代。
如果你想加速代码,你需要加快实际需要时间的部分,而不是每次迭代尝试几百纳秒(仍然不到1微秒)通过改变你的方式正在迭代。查找“代码分析”(here's a good link to get you started),获取有关如何识别代码缓慢部分的指导。