2012-04-28 80 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