低效循环中的R

低效循环中的R

问题描述:

早上好,低效循环中的R

我一直在开发中的R几个月,我必须确保我的代码的执行时间不会太长,因为我分析大数据集。

因此,我一直在尝试使用尽可能多的矢量化函数。

但是,我仍然在想什么。

什么是R的代价不是循环本身的权利? 我的意思是,当你开始修改循环中的变量时会出现问题,例如,是否正确?

因此,我在想,如果你只需要在每个元素上运行一个函数(实际上你不关心结果)。例如在数据库中写入数据。你该怎么办?

1)使用mapply而不在任何地方存储结果?

2)在矢量上做一个循环,只对每个元素应用f(i)?

3)有没有更好的功能,我可能错过了? (这当然假设你的功能没有最佳的矢量化)。

怎么样foreach包?你有没有经历过任何使用它的性能改进?

+1

我会离开这个答案的人谁更专业比我,但在我的实践经验,通常是*应用功能(但不总是)加快了一点。 – nico 2010-06-28 06:37:31

+0

我想是这样,因为循环完成“在C”中,而不是直接通过R. – SRKX 2010-06-28 08:16:45

+1

看到这个SO贴在申请家庭 - http:// stackoverflow。com/questions/2275896/is-rs-apply-family-more-syntactic-sugar – csgillespie 2010-06-28 09:28:33

只是一些评论。 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?"

+0

是不是应用函数更好地处理循环的C实现仍然更好? 这个问题实际上是一般的,使用Reduce实现一个简单的循环(例如)在你看来更好? – SRKX 2010-06-28 09:55:49

+3

在'sapply'版本中,大部分时间都花在了后处理结果上。当你执行'system.time(sinI Marek 2010-06-28 10:01:05

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