2012-04-28 3 views
6

Я всегда был немного обеспокоен отсутствием точности. Я вижу табличку с маркировкой system.time и rbenchmark (в том, что точность синхронизации может отсутствовать), и недавно увидел Hadley ссылку на пакет microbenchmark. Поэтому я решил дать ему вихрь, как показано ниже. Я провел mean против f <- function(x) {sum(x)/length(x)} и ожидал mean, чтобы сделать способ лучше, чем f, но результаты, как я их понимаю, не указывают, что это правда.неожиданные результаты: microbenchmark

  1. Я не понимаю результаты?
  2. Действительно ли это быстрее, чем означает?
  3. Микробиблиотека все еще находится в бета-фазе, и ее нужно гладить ?

Я запускаю R2.15 на машине с выигрышем 7 (так как микробиблиотека выполняет тайминги по-разному в зависимости от вашей ОС).

Результаты

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, которая может отображаться в одном из этих релизов (пока не проверяйте github). Примеры: http://stackoverflow.com/a/6919493/636656 –

+0

Это может быть объяснено http://radfordneal.wordpress.com/2014/02/02/inaccurate-results-from-microbenchmark/ – Momo

+0

Возможно, не все данные для 'f' были ниже, и диаграмма рассеяния также указала это. Джоран прибил это. –

ответ

8

Я могу ошибаться, но это не кажется, что для меня удивительно. Перед тем, как mean.default может позвонить .Internal(mean(x)), необходимо проверить операторы 0 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

Спасибо. Я сделал предположение и не проверял. Лучшая проверка микробизнеса будет «sum» против «Уменьшить»: sum2 <- function (x) Уменьшить («+», x) », что дает ожидаемые результаты. Я думаю, мне понравится 'microbenchmark' –

+1

Просто пробежал по этому поводу в несвязанных чтениях. Видимо, это несколько печально известно: http: //lookingatdata.blogspot.se/2011/04/speeding-up-r-computations.html –

2

Я думаю, вы обнаружите, что если вы увеличите до размера X с коэффициентом 10, вы увидите более стабильные результаты. Честно говоря, я был бы удивлен, если бы вы действительно смогли получить микросекундную точность времени на компьютере с многозадачной операционной системой.

Вы могли бы также рассмотреть следующие вопросы:

  • Вы работаете на ноутбуке или компьютере, который имеет автоматическое масштабирование частоты процессора?
  • Warmup?
  • Привязка вашего процесса к одному ядру.
+0

Часть красоты «microbenchmark» заключается в том, что она работает много раз, поэтому вы можете видеть, как результаты меняются, поэтому я предполагаю, что то, что работает в фоновом режиме не влияет на результаты ожидания. –

+0

@ gsk3 посмотреть время вывода, и вы увидите длинный хвост, так что ... hist (res [res $ expr == 'f (x)', 'time']/length (x), breaks = 90) – Sean

+0

Конечно, но медиана, вероятно, довольно хорошая оценка, нет? –