2012-04-28 107 views
6

我一直對缺乏準確性有些迷惑,我看到system.timerbenchmark(因爲時間的精度可能不足),並看到Hadley最近參考了microbenchmark包。所以我決定給它一個旋轉,如下所示。我將meanf <- function(x) {sum(x)/length(x)}對齊,預計meanf做得更好,但據我瞭解,結果並不表明這是真的。意想不到的結果:microbenchmark

  1. 我誤解了結果嗎?
  2. f實際上是否比平均速度更快?
  3. microbenchmark仍處於測試階段,這需要熨燙 了嗎?

我在贏得7臺機器上運行R2.15(因爲microbenchmark的定時不同,具體取決於您的操作系統)。

結果

Unit: microseconds 
    expr min  lq median  uq max 
1 f(x) 19.130 20.529 20.529 20.996 286.00 
2 mean(x) 28.927 29.860 30.327 30.327 672.31 

守則

library(microbenchmark) 

x <- 1:10000 
f <- function(x) {sum(x)/length(x)} 
mean(x) 

res <- microbenchmark(
    mean(x), 
    f(x), 
times=1000L) 

print(res) 
boxplot(res) 
+0

我喜歡'microbenchmark'。如果你做的不止一個或兩個結果,繪圖可以幫助很大,但是在醜陋的一面,默認輸出是一點點。我爲ggplot2寫了一個autoplot函數,可能會在其中一個版本中顯示(同時檢查github)。示例:http://stackoverflow.com/a/6919493/636656 – 2012-04-28 16:52:09

+0

這可能解釋它http://radfordneal.wordpress.com/2014/02/02/inaccurate-results-from-microbenchmark/ – Momo 2014-02-02 23:31:56

+0

可能不是所有的統計數據'f'較低,散點圖也表明了這一點。喬蘭釘了這一個。 – 2014-02-03 02:21:01

回答

8

我可能是錯的,但是這似乎並不使人感到意外給我。在mean.default之前可以調用.Internal(mean(x))它必須檢查3 if語句,計算長度x,然後檢查另一個if語句。它的時代差異相當小。

調用.Internal(mean(x)直接稍微快一點還是:

library(microbenchmark) 

x <- 1:10000 
f1 <- function(x) {sum(x)/length(x)} 
f2 <- function(x) {.Internal(mean(x))} 

res <- microbenchmark(
    mean(x), 
    f1(x), 
    f2(x), 
times=1000L) 

print(res) 

Unit: microseconds 
    expr min  lq median  uq  max 
1 f1(x) 32.195 32.4605 32.8850 33.4645 106.997 
2 f2(x) 21.840 22.0580 22.2015 22.6270 55.316 
3 mean(x) 35.393 35.9840 36.1860 36.4420 91.203 
+0

謝謝。我做了一個假設,並沒有檢查它。更好地檢查微基準將與'Reduce'版本'求和':sum2 < - function(x)Reduce(「+」,x)'產生預期結果。我想我會喜歡'microbenchmark' – 2012-04-28 16:12:44

+1

只是在無關的讀數中跑過這個。顯然,意思是有點臭名昭着:http://lookingatdata.blogspot。seo/2011/04/speeding-up-r-computations.html – 2012-04-28 17:21:59

2

我想你會發現,如果你用10倍撞了X的大小,你會看到更一致的結果。說實話,如果你真的可以在具有多任務操作系統的計算機上獲得微秒定時精度,我會感到驚訝。

您也可以考慮:

  • 你在筆記本電腦或具有自動的CPU頻率調節機器運行?
  • 熱身?
  • 固定你的進程到一個核心。
+0

'microbenchmark'的美妙之處在於它運行很多次,所以你可以看到結果如何變化,所以我猜想運行的是什麼在後臺對預期結果沒有影響。 – 2012-04-28 16:46:11

+0

@ gsk3查看輸出時間,你會看到一個長尾巴,所以像... hist(res [res $ expr =='f(x)','time']/length(x ),休息= 90) – Sean 2012-04-28 20:29:45

+0

當然,但中位數可能是一個相當不錯的估計,不是嗎? – 2012-04-28 20:58:45