Доброе утро,
Я разрабатывал в течение нескольких месяцев в R, и я должен удостовериться, что время выполнения моего кода не является слишком длинным, потому что я анализирую большие наборы данных.
Следовательно, я пытался использовать как можно больше векторизованные функции.
Однако я все еще задаюсь вопросом что-то.
То, что является дорогостоящим в R, не является самим циклом право? Я имею в виду, проблема возникает, когда Вы начинаете изменять переменные в цикле, например, это исправляет?
Следовательно я думал, что, если просто необходимо выполнить функцию на каждом элементе (Вы на самом деле не заботитесь о результате). Например, записать данные в базе данных. Что необходимо сделать?
1) использовать mapply, не храня результат нигде?
2) цикл по вектору и только применяют f (i) к каждому элементу?
3) существует ли лучшая функция, которую я, возможно, пропустил?
(это, конечно, предполагает, что Ваша функция оптимально не векторизована).
Что относительно foreach
пакет? Вы испытали какое-либо повышение производительности при помощи его?
Только пара комментариев. Цикл for
примерно так же быстр, как apply
и его варианты, а реальное увеличение скорости происходит, когда вы максимально векторизуете свою функцию (то есть используете низкоуровневые циклы, а не apply
, который просто скрывает цикл for
). Я не уверен, что это лучший пример, но рассмотрим следующий:
> n <- 1e06
> sinI <- rep(NA,n)
> system.time(for(i in 1:n) sinI[i] <- sin(i))
user system elapsed
3.316 0.000 3.358
> system.time(sinI <- sapply(1:n,sin))
user system elapsed
5.217 0.016 5.311
> system.time(sinI <- unlist(lapply(1:n,sin),
+ recursive = FALSE, use.names = FALSE))
user system elapsed
1.284 0.012 1.303
> system.time(sinI <- sin(1:n))
user system elapsed
0.056 0.000 0.057
В одном из комментариев ниже Марек указывает, что самая трудоемкая часть цикла for
выше - это часть ]<-
:
> system.time(sinI <- unlist(lapply(1:n,sin),
+ recursive = FALSE, use.names = FALSE))
user system elapsed
1.284 0.012 1.303
Узкие места, которые не могут быть немедленно векторизованы, могут быть переписаны на C или Fortran, скомпилированы с помощью R CMD SHLIB
, а затем подключены с помощью . Call
, .C
или .Fortran
.
Также смотрите эти ссылки для получения дополнительной информации об оптимизации циклов в R. Также ознакомьтесь со статьей "Как избежать этого цикла или сделать его быстрее?" в R News.