低效循环中的R
问题描述:
早上好,低效循环中的R
我一直在开发中的R几个月,我必须确保我的代码的执行时间不会太长,因为我分析大数据集。
因此,我一直在尝试使用尽可能多的矢量化函数。
但是,我仍然在想什么。
什么是R的代价不是循环本身的权利? 我的意思是,当你开始修改循环中的变量时会出现问题,例如,是否正确?
因此,我在想,如果你只需要在每个元素上运行一个函数(实际上你不关心结果)。例如在数据库中写入数据。你该怎么办?
1)使用mapply而不在任何地方存储结果?
2)在矢量上做一个循环,只对每个元素应用f(i)?
3)有没有更好的功能,我可能错过了? (这当然假设你的功能没有最佳的矢量化)。
怎么样foreach
包?你有没有经历过任何使用它的性能改进?
答
只是一些评论。 A for
循环大致与apply
及其变体一样快,并且当您尽可能地引导功能时(即使用低级循环而不是apply
,它仅隐藏for
循环),真正的加速会出现, 。我不知道这是否是最好的例子,但考虑到以下几点:
> n <- 1e06
> sinI <- rep(NA,n)
> system.time(for(i in 1:n) sinI[i] <- sin(i))
user system elapsed
3.316 0.000 3.358
> system.time(sinI <- sapply(1:n,sin))
user system elapsed
5.217 0.016 5.311
> system.time(sinI <- unlist(lapply(1:n,sin),
+ recursive = FALSE, use.names = FALSE))
user system elapsed
1.284 0.012 1.303
> system.time(sinI <- sin(1:n))
user system elapsed
0.056 0.000 0.057
在下面的意见之一,马立克指出,消费for
环路的一部分上面的时间实际上是]<-
部分:
> system.time(sinI <- unlist(lapply(1:n,sin),
+ recursive = FALSE, use.names = FALSE))
user system elapsed
1.284 0.012 1.303
不能立即矢量化可以用C或Fortran的重写,与R CMD SHLIB
编译,然后插入带.Call
,.C
或.Fortran
的瓶颈。
此外,请参阅theselinks了解更多关于R中循环优化的信息。另请参阅R News中的文章"How Can I Avoid This Loop or Make It Faster?"。
答
vapply通过要求您指定返回值是什么来避免后处理。 它原来是要快3.4倍的for循环:
> system.time(for(i in 1:n) sinI[i] <- sin(i))
user system elapsed
2.41 0.00 2.39
> system.time(sinI <- unlist(lapply(1:n,sin), recursive = FALSE, use.names = FALSE))
user system elapsed
1.46 0.00 1.45
> system.time(sinI <- vapply(1:n,sin, numeric(1)))
user system elapsed
0.71 0.00 0.69
我会离开这个答案的人谁更专业比我,但在我的实践经验,通常是*应用功能(但不总是)加快了一点。 – nico 2010-06-28 06:37:31
我想是这样,因为循环完成“在C”中,而不是直接通过R. – SRKX 2010-06-28 08:16:45
看到这个SO贴在申请家庭 - http:// stackoverflow。com/questions/2275896/is-rs-apply-family-more-syntactic-sugar – csgillespie 2010-06-28 09:28:33