Estilo de escrita R - exige vs. ::
OK, todos nós estamos familiarizados com o operador de dois pontos no R. Sempre que estou prestes a escrever alguma função, eu usorequire(<pkgname>)
, mas eu estava sempre pensando em usar::
em vez de. Usandorequire
em funções personalizadas é melhor prática do quelibrary
, Desde arequire
retorna aviso eFALSE
ao contráriolibrary
, que retornará erro se você fornecer um nome de pacote inexistente.
Por outro lado,::
O operador obtém a variável do pacote, enquantorequire
carrega todo o pacote (pelo menos, espero), então as diferenças de velocidade vieram primeiro à minha mente.::
deve ser mais rápido querequire
.
E fiz algumas análises para verificar isso - escrevi duas funções simples que carregamread.systat
função deforeign
pacote, comrequire
e::
respectivamente, portanto, importarIris.syd
conjunto de dados fornecido comforeign
pacote, funções replicadas 1000 vezes cada (o que era descaradamente arbitrário) e ... triturava alguns números.
Estranhamente (ou não), encontrei diferenças significativas em termos de CPU do usuário e tempo decorrido, enquanto não houve diferenças significativas em termos de CPU do sistema. E ainda mais estranha conclusão:::
é realmente mais lento! Documentação para::
é muito franco, e apenas olhando as fontes, é óbvio que::
deve ter um desempenho melhor!
exigir
#!/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()
dois pontos
#!/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()
Pegue dados CSVaqui. Algumas estatísticas:
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 é a classificação média pararequire
, MRc ibid para::
. Eu devo ter feito algo errado aqui. Simplesmente não faz sentido ... Tempo de execução para::
parece muito mais rápido !!! Eu posso ter estragado alguma coisa, você não deve descartar essa opção ...
OK ... perdi meu tempo para ver que há alguma diferença e realizei uma análise completamente inútil, então, voltando à pergunta:
"Por que alguém deveria preferirrequire
sobre::
ao escrever uma função?"
=)