2016-02-11 166 views
0

a^2a^2L之間是否有差異R^2和^ 2L有區別嗎?

速度差?

精度?

到目前爲止,我看不到任何人,只是想知道^ 2是作爲log/exp對實現的,而^ 2L作爲乘法。那麼如果a不只是一個向量?

UPDATE

不,這不是重複的,我知道22L之間的差異。問題是,這種差異是否對電力運營商起作用?

+6

關於是否有差異,你可以自己做基準... – akrun

+0

也許吧。 [mlutils.c](https://github.com/wch/r-source/blob/b156e3a711967f58131e23c1b1dc1ea90e2f0c43/src/nmath/mlutils.c)有'R_pow'和'R_pow_di',但我沒有檢查更遠的上游以查看解析器是否使用了'R_pow_di'。 –

+0

關於速度的FWIW,使用'2'的速度比使用'2L'的速度略快,但差別是可以忽略不計(我的機器上的平均差10毫秒,長度爲1e7的矢量) – Heroka

回答

4

R在內部使用整數指數版本R_pow_di,但^ operator僅調用R_pow。也就是說,R_pow確實特例x^2作爲。因此,精度是相同的,但2L版本應該稍慢,因爲在C級長時間>雙倍強制。這在下面的基準中得到了證明。

lngs<-rep(2L,1e6) 
dbls<-rep(2.0,1e6) 
n<-sample(100,1e6,replace=TRUE) 
x<-rnorm(1e6) 
microbenchmark(x^lngs,x^dbls,n^lngs,n^dbls) 
# Unit: milliseconds 
# expr  min  lq  mean median  uq  max neval cld 
# x^lngs 8.489547 9.804030 12.543227 11.719721 13.98702 19.92170 100 b 
# x^dbls 5.622067 6.724312 9.432223 7.949713 10.89252 59.15342 100 a 
# n^lngs 10.590587 13.857297 14.920559 14.200080 16.65519 19.55346 100 c 
# n^dbls 8.331087 9.699143 12.414267 11.403211 14.20562 19.66389 100 b 

這沒什麼可以讓我們失眠。

鏈接轉到源鏡像。請注意,R_ADD,R_SUB,R_MULR_DIV被定義爲利用類型過載的C宏,但R_POW被定義爲內嵌x^2 = x*x特殊情況,然後調用R_pow(小寫)。在R_pow中再次檢查該特殊情況將是重複的,但R_pow在內部被稱爲其他地方。

5

我的結論是,這是有史以來所以,稍微快當且僅當基本是一個整數,以及,標量

我的風向標:

library(microbenchmark) 
set.seed(1230) 
num <- rnorm(1L) 
int <- sample(100L, 1L) 
microbenchmark(times = 100000L, 
       num^2L, 
       num^2, 
       int^2L, 
       int^2) 

而且我的機器上的時序:

# Unit: nanoseconds 
# expr min lq  mean median uq  max neval 
# num^2L 99 115 161.8495 121 166 11047 1e+05 
# num^2 97 113 196.8615 119 165 3645369 1e+05 
# int^2L 89 107 140.3745 111 120  3319 1e+05 
# int^2 98 115 525.1727 120 166 34776551 1e+05 

如果基或指數是一個數字的中位時間基本上是相同的(雖然也許num^num有脂肪高尾?)。

尺寸

的刑罰儘管integer^integer標量,它出現的優勢(在他自己的答案闡明通過@ A.Webb),對於任何合理大小的矢量,numeric^numeric速度更快,而且,對於相當常見的中等尺寸範圍的矢量,速度要快得多。從500點的基準

結果:

set.seed(1230) 
ns <- as.integer(10^(seq(0, 6, length.out = 500L))) 
mbs <- sapply(ns, function(n){ 
    num = rnorm(n); int = as.integer(num) 
    summary(microbenchmark(times = 2000L, num^2L, num^2, int^2L, int^2), 
      unit = "relative")$median 
}) 

5k

這第一條曲線得到的東西的要點。 n表示numerici表示integer

最後,向量的大小的固定成本併吞噬的優點:

1e6

只有在可忽略的長度是i^i最快:

50


繪圖的要點是:

matplot(ns[ns < 5000], t(mbs[ , ns < 5000]), 
     type = "l", lty = 1L, lwd = 3L, 
     xlab = "length", ylab = "Relative Time", 
     main = "Through Length 5000", 
     col = c("black", "red", "green", "blue")) 
legend("topleft", c("n^i", "n^n", "i^i", "i^n"), 
     col = c("black", "red", "green", "blue"), 
     lty = 1L, lwd = 3L)