OK, nous sommes tous familiers avec double opérateur deux points dans l'affaire R. Chaque fois que je suis sur le point d'écrire une fonction, j'utilise require(<pkgname>)
, mais je pense toujours à l'aide ::
à la place. L'utilisation de require
dans les fonctions personnalisées est une meilleure pratique que library
, puisque require
renvoie l'avertissement et FALSE
, contrairement à library
, qui renvoie une erreur si vous indiquez un nom de package inexistant. D'autre part, l'opérateur ::
obtient la variable de l'emballage, alors que require
charge l'ensemble du paquet (du moins je l'espère), donc les différences de vitesse sont apparues en premier. ::
doit être plus rapide que require
.R style d'écriture - exigent par rapport ::
Et je l'ai fait une analyse afin de vérifier que - j'ai écrit deux fonctions simples qui charge read.systat
fonction du paquet foreign
, avec require
et ::
respectivement, par conséquent importer Iris.syd
ensemble de données livré avec paquet foreign
, fonctions répliquées 1000 fois chacun (qui était sans vergogne arbitraire), et ... croqué quelques chiffres. Bizarrement (ou pas) j'ai trouvé des différences significatives en termes de CPU utilisateur et de temps écoulé, alors qu'il n'y avait pas de différences significatives en termes de CPU système. Et encore plus étrange conclusion: ::
est en réalité plus lent! Documentation pour ::
est très contondant, et juste en regardant les sources, il est évident que ::
devrait fonctionner mieux!
nécessitent
#!/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()
côlon à double
#!/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()
Grab données CSV here. Quelques statistiques:
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 est de rang moyen pour require
, ibid MRc pour ::
. Je dois avoir fait quelque chose de mal ici. Cela n'a tout simplement aucun sens ... Le temps d'exécution pour ::
semble beaucoup plus rapide !!! J'ai peut-être foiré quelque chose, vous ne devriez pas abandonner cette option ...
OK ... J'ai perdu mon temps afin de voir qu'il y a une différence, et j'ai effectué une analyse complètement inutile, donc , revenir à la question:
"Pourquoi doit-on préférer require
sur ::
lors de l'écriture d'une fonction?"
=)
Est-ce pour les fonctions autonomes ou fonctions dans un package? – hadley
En outre, vous auriez normalement besoin de() une fois en haut de votre script, pas une fois dans chaque appel de fonction. – hadley
C'est pour les fonctions autonomes. Je développe une application web, et comme RApache démarre une nouvelle session R à chaque requête HTTP, j'essaie d'éviter une charge de serveur inutile. Cet exemple est inapproprié - une fois que vous avez importé un fichier, le travail est terminé, mais dans une application Web interactive avec un tas d'appels AJAX, cela peut être très inefficace. – aL3xa