好的,我们都熟悉 R 中的双冒号运算符。每当我要编写一些函数时,我都会使用 require(<pkgname>)
,但我一直在考虑使用 ::
反而。使用 require
在自定义函数中比 library
更好的实践, 自 require
返回警告和 FALSE
,不像 library
,如果您提供不存在的包的名称,则会返回错误。
另一方面,::
运算符从包中获取变量,而 require
加载整个包(至少我希望如此),所以我首先想到的是速度差异。 ::
必须比 require
快.
我做了一些分析以检查这一点 - 我已经编写了两个加载 read.systat
的简单函数。函数来自 foreign
包,带 require
和 ::
分别,因此导入 Iris.syd
foreign
附带的数据集打包,每个函数复制 1000 次(这是无耻的任意),然后......处理了一些数字。
奇怪的是(或不是)我发现在用户 CPU 和运行时间方面存在显着差异,而在系统 CPU 方面没有显着差异。还有更奇怪的结论:::
其实更慢! ::
的文档非常直率,仅通过查看来源就很明显::
应该表现更好!
要求
#!/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 数据 here .一些统计数据:
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 同上 ::
.我一定是在这里做错了什么。它只是没有任何意义... ::
的执行时间似乎更快!我可能搞砸了什么,你不应该放弃那个选项......好吧...我浪费了我的时间来看看有什么不同,我进行了完全无用的分析,所以,回到问题:
“为什么在编写函数时应该更喜欢
require
而不是 ::
?”=)
最佳答案
"Why should one prefer require over :: when writing a function?"
我通常更喜欢
require
由于很好的 TRUE/FALSE 返回值,它让我可以在进入代码之前处理包不可用的可能性。尽早崩溃,而不是分析到一半。我只用
::
当我需要确保我使用的是正确版本的函数,而不是来自其他包的版本时,会屏蔽名称。On the other hand, :: operator gets the variable from the package, while require loads whole package (at least I hope so), so speed differences came first to my mind. :: must be faster than require.
我认为您可能忽略了
foreign
使用的延迟加载的影响。包装根据 the first page of its manual .本质上,使用延迟加载的包会延迟对象(例如函数)的加载,直到第一次调用这些对象。因此,您认为“::
必须比要求更快”的论点不一定正确,因为 foreign
当您使用 require
附加它时,没有将其所有内容加载到内存中.有关延迟加载的完整详细信息,请参阅 Prof. Ripley's article在 RNews,第 4 卷,第 2 期。
关于R 编写风格 - 需要与::,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4372145/