Хорошо, мы все знакомы с оператором двойной толпы в R. Когда я собираюсь написать какую-то функцию, я использую require(<pkgname>), но я всегда думал об использовании ::. Использование require в пользовательских функциях лучше, чем library, поскольку require возвращает предупреждение и FALSE, в отличие от library, который возвращает ошибку, если вы указываете имя несуществующего пакета.
С другой стороны, оператор :: получает переменную из пакета, а require загружает весь пакет (по крайней мере, я надеюсь, что так), поэтому на мой взгляд возникли различия в скорости. :: должен быть быстрее, чем require.
И я сделал некоторый анализ, чтобы проверить это - я написал две простые функции, которые загружают функцию read.systat из пакета foreign, с require и :: соответственно, поэтому импортируйте набор данных Iris.syd, который корабли с пакетом foreign, реплицированные функции 1000 раз каждый (что было бесстыдно произвольно) и... хрустели некоторые цифры.
Странно (или нет) я обнаружил существенные различия с точки зрения пользовательского процессора и прошедшего времени, тогда как существенных различий в системном процессоре не было. И еще более странный вывод: :: на самом деле медленнее! Документация для :: очень тупая, и, просто взглянув на источники, очевидно, что :: должен работать лучше!
требуется
#!/usr/local/bin/r
## with require
fn1 <- function() {
require(foreign)
read.systat("Iris.syd", to.data.frame=TRUE)
}
## times
n <- 1e3
sink("require.txt")
print(t(replicate(n, system.time(fn1()))))
sink()
двойной двоеточие
#!/usr/local/bin/r
## with ::
fn2 <- function() {
foreign::read.systat("Iris.syd", to.data.frame=TRUE)
}
## times
n <- 1e3
sink("double_colon.txt")
print(t(replicate(n, system.time(fn2()))))
sink()
Возьмите CSV-данные здесь. Некоторая статистика:
user CPU: W = 475366 p-value = 0.04738 MRr = 975.866 MRc = 1025.134
system CPU: W = 503312.5 p-value = 0.7305 MRr = 1003.8125 MRc = 997.1875
elapsed time: W = 403299.5 p-value < 2.2e-16 MRr = 903.7995 MRc = 1097.2005
MRr - средний ранг для require, MRc ibid для ::. Я, должно быть, сделал что-то не так. Это просто не имеет никакого смысла... Время выполнения для :: кажется быстрее! Возможно, я что-то прикрутил, вы не должны отбрасывать этот вариант...
ОК... Я потратил свое время, чтобы увидеть, что есть какая-то разница, и я провел совершенно бесполезный анализ, поэтому вернемся к вопросу:
"Зачем нужно писать require над :: при записи функции?"
=)