为什么使用`{}`的R代码比用`()`快的代码?

时间:2013-04-10 12:59:20

标签: r

为什么带有{}的R代码通常比带有()的代码更快,例如下面的代码?

n=10000000
w1=numeric(n)
w2=numeric(n)
r=rnorm(n)


t1=Sys.time()
for(i in 1:n)
w1[i]=((r[i]^2))*(1*1)
t1-Sys.time()


t1=Sys.time()
for(i in 1:n)
w2[i]={{r[i]^2}}*{1*1}
t1-Sys.time()

2 个答案:

答案 0 :(得分:9)

baptiste 已经在评论中链接了 Radford Neal 的博客。
但由于SE人不喜欢外部网站的链接,让我引用作者本人的一个有趣的评论(评论33):

  

是的,圆括号仍然比R 2.13.1和最新的R 2.14.1中的花括号慢,但不如之前那么多(我建议减少内置函数的一般开销的补丁被包含在内在后来的版本中,这减少了这种差异。)

     

圆括号没有充分的理由变慢。我建议另一个改变(只需几行代码),这将加快括号。 Luke Tierney回答说,这个补丁不应该被整合到R中,因为括号是一个像sqrt 这样的运算符,并且因此在代码中应该没有任何实现括号的代码与像sqrt这样的运营商已经实施。

知道,( )似乎是一个操作员 - 就​​像一个基本没什么作用的功能一样 -
{ }是一种语言结构 括号( )包含了所有操作符共有的一些开销代码,实际上并不需要它们。

答案 1 :(得分:5)

Lukas很好地回答了这个问题,但是对于那些感兴趣的人(这可以通过矢量化代码来有效删除),这里有一些时间安排。

brace <- function(n){
w1=numeric(n)
w2=numeric(n)
r=rnorm(n)
for(i in 1:n)
w1[i]=((r[i]^2))*(1*1)
}


curly <- function(n){
w1=numeric(n)
w2=numeric(n)
r=rnorm(n)
for(i in 1:n)
w2[i]={{r[i]^2}}*{1*1}
}



microbenchmark( curly(1e5) , brace(1e5) , times = 50 ) 
Unit: milliseconds
         expr      min       lq   median       uq      max neval
 curly(1e+05) 311.4245 318.8916 324.1990 335.0928 400.8555    50
 brace(1e+05) 315.5428 323.8860 328.7982 350.7268 406.5785    50

1e5环长度差异大约为5毫秒。所以让我们删除循环:

braceV <- function(n){
w1=numeric(n)
w2=numeric(n)
r=rnorm(n)
w1=((r^2))*(1*1)
}


curlyV <- function(n){
w1=numeric(n)
w2=numeric(n)
r=rnorm(n)
w2={{r^2}}*{1*1}
}

microbenchmark( curlyV(1e5) , braceV(1e5) , times = 50 )
Unit: milliseconds
          expr      min       lq    median       uq      max neval
 curlyV(1e+05) 9.014361 9.284532  9.666867 10.81317 37.82510    50
 braceV(1e+05) 9.029408 9.373773 10.293302 10.83487 37.76596    50

差异现在约为0.5毫秒。