为什么 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()
为什么 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()
baptiste已经在评论中链接了Radford Neal的博客。
但是由于 SE 人不喜欢链接到外部网站,让我引用作者本人的一个有趣的评论(评论 33):
是的,在 R 2.13.1 和最新的 R 2.14.1 中,括号仍然比大括号慢,尽管没有以前那么快(我建议减少内置函数中的一般开销的补丁在以后的版本中被引入,这减少了这种差异)。
没有充分的理由让括号变慢。我建议进行另一项更改(仅几行代码),以加快括号的速度。Luke Tierney 回应说,这个补丁不应该被合并到 R 中,因为括号就像 sqrt 一样是一个运算符,因此在实现括号的代码中应该没有任何东西与像 sqrt 这样的运算符的实现方式不同。
知道这一点,( )
似乎是一个运算符 - 很像一个基本上什么都不做的函数 -
而是{ }
一个语言结构。
括号( )
包含了所有运算符共有的一些开销代码,实际上它们不需要它们。
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 毫秒。