При работе с векторами в R функция diff
вычисляет различия между каждым значением и предыдущим. Из ?diff
:Почему R diff работает медленно?
Если
x
вектор длиныn
иdifferences = 1
, то вычисленный результат равен последовательных разностейx[(1+lag):n] - x[1:(n-lag)]
Однако, когда я тестировал время выполнения diff
функции против их теоретическое выражение (с использованием microbenchmark
функция от microbenchmark
пакета), функция diff
работает медленнее. Вот мой код:
library(microbenchmark)
mb.diff1 <- function(n, seed){
set.seed(seed)
vec <- runif(n)
out <- diff(vec)
return(out)
}
mb.diff2 <- function(n, seed){
set.seed(seed)
vec <- runif(n)
out <- vec[2:n]-vec[1:(n-1)]
return(out)
}
times.diff1 <- c()
times.diff2 <- c()
vec.sizes <- c(1e1, 1e2, 1e3, 1e4)
for (n in vec.sizes){
bench <- microbenchmark(
mb.diff1(n,1),
mb.diff2(n,1))
times.median <- aggregate(
bench$time,
by = list(bench$expr),
FUN = median)
times.diff1 <- c(times.diff1, times.median[1,2])
times.diff2 <- c(times.diff2, times.median[2,2])
}
perf.ratio <- times.diff1/times.diff2
names(perf.ratio) <- vec.sizes
print(perf.ratio)
я закончил с vec.sizes из 1E4, так что время excution для вас, ребята, не слишком долго, но я заставляю их идти до 1e7. Вы можете увидеть здесь результаты:
Как вы можете видеть, функция diff
является медленнее всех векторных размеров. Фактор имеет тенденцию уменьшаться, поскольку в обоих случаях время исполнения является линейной функцией от векторного размера, поэтому мы не можем сказать, что diff
лучше работает с ростом n. Таким образом, возникают вопросы:
- (Очевидный вопрос) Я делаю что-то неправильно в своем коде при измерении времени выполнения?
- Что может быть причиной того, что функция
diff
работает медленнее, чем их теоретическое выражение? - Знаете ли вы самый эффективный способ вычисления вектора различий, чем
x[(1+lag):n] - x[1:(n-lag)]
?
Я использую R 3.1.2 в Linux.
спасибо, что заранее.
R-3.1.2 составляет более 2 лет. Ваши тайминги включают в себя создание случайного вектора, поэтому вы не изолируете разницу, о которой вы спрашиваете. Используя упрощенные функции, которые только называет 'diff' и' vec [] ',' diff' быстрее на моем компьютере Ubuntu 14.04 с R-3.3.2. 'diff' также является общим, поэтому есть некоторая стоимость отправки метода. Вызов 'diff.default' напрямую (обычно не рекомендуется) выполняется быстрее. –
Также 'diff.default' преобразует свой вход в матрицу и выполняет некоторую проверку. https://github.com/wch/r-source/blob/trunk/src/library/base/R/diff.R –
Спасибо @JoshuaUlrich, я обновил свой Ubuntu до 16.04 и установил R 3.3.2.Я также принял вызов runif за пределами функций, чтобы я мог измерить реальное время выполнения наших функций diff. Whit all that, diff выполняет немного лучше для векторов, больших 1e4. Я полагаю, что лучшая производительность vec [] для небольших размеров обусловлена проверкой. Большое спасибо. –