R - 根据先前迭代的结果应用或for循环

时间:2018-06-01 20:10:25

标签: r for-loop apply

我目前正在处理一个问题,我执行多个函数是迭代执行的。每次迭代时,输入都取决于前一次运行的结果。目前我使用了'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函数会导致计算时间减少吗?

1 个答案:

答案 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),获取有关如何识别代码缓慢部分的指导。