【发布时间】:2011-05-21 07:19:07
【问题描述】:
好的,我们都熟悉R中的双冒号运算符。每当我要编写一些函数时,我都会使用require(<pkgname>),但我一直在考虑使用::。在自定义函数中使用require 比library 更好,因为require 返回警告和FALSE,不像library,如果你提供一个不存在的包的名称会返回错误。
另一方面,:: 运算符从包中获取变量,而require 加载整个包(至少我希望如此),所以我首先想到的是速度差异。 :: 必须比 require 快。
我做了一些分析以检查 - 我编写了两个简单的函数,从 foreign 包加载 read.systat 函数,分别使用 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 而不是::?”
=)
【问题讨论】:
-
这是针对独立函数还是包中的函数?
-
另外,您通常会在脚本顶部使用一次 require(),而不是在每个函数调用中都使用一次。
-
用于独立功能。我正在开发一个 Web 应用程序,并且由于 RApache 在每个 HTTP 请求时都会启动新的 R 会话,因此我试图避免不必要的服务器负载。这个例子是不合适的——一旦你导入一个文件,工作就完成了,但是在一个带有一堆 AJAX 调用的交互式 webapp 中,这可能是非常低效的。
标签: r namespaces packages