Хорошо, мы все знакомы с оператором двойной толпы в 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
над ::
при записи функции?"
=)