【发布时间】:2016-02-11 11:27:51
【问题描述】:
我目前正在编写一个调用特定函数的代码,具体取决于向量中元素的值。那么,我的问题是这是否有效。如果我正确理解了ifelse 算法,那么我作为函数的第二个和第三个参数输入的任何值都会被完整计算,然后根据我的条件的TRUE 或FALSE 值进行子集化。这与我们在编码中看到的典型if/else 结构形成对比,在这种结构中,我们会评估一个条件,然后只有在我们知道要运行哪个函数时才在元素上运行一个函数。为了测试这一点,我尝试使用以下内容:
test1 <- function() {
x <- sample(1:1e9, 1e6, replace = TRUE)
y <- ifelse(x %% 2 == 0, x**2, x/2)
return(y)
}
test2 <- function() {
x <- sample(1:1e9, 1e6, replace = TRUE)
y <- numeric(length(x))
for (i in 1:length(x)) {
if (x[i] %% 2 == 0) {
y[i] <- x[i]**2
} else {
y[i] <- x[i]/2
}
}
return(y)
}
microbenchmark::microbenchmark(test1(), test2(), times = 1000)
Unit: milliseconds
expr min lq mean median uq max neval
test1() 2.366067 2.494746 8.27343 2.580164 2.706826 1690.049 1000
test2() 21.773385 23.050818 29.70450 23.712907 29.468783 3169.008 1000
平均值似乎表明ifelse 方法优于if/else。
我问的原因是因为我将要解析相对较大的 XML 文件,并且我实现的解析方法将根据树中子项的布局而有所不同,我试图成为尽可能高效。
所以有两个问题:1) 我上面的结论是否正确,ifelse 比 if/else 快,2) ifelse 是否计算 yes 和 no 向量的所有值,然后对它们进行子集化?
提前致谢。
编辑
上面的代码以及一些问题文本已被修改以反映下面的 cmets。
【问题讨论】:
-
ifelse有一大堆检查输入等,你的test2函数没有。这可能解释了大部分纳秒的差异。ifelse的核心本质上是一个if/else,与您拥有的相同 + 对NA值的一些调整。 -
您的
test2有错误;尝试自己运行它。此外,您的基准测试命令应该调用test1()和test2(),否则它实际上并没有运行代码。 -
如果你真的想看看性能差异,预先模拟
x并将它传递给你的函数。 -
@aaron 好电话!我会更新问题以反映这一点。
-
另请参阅帮助文件中
Warning部分下的建议,其中提供了可能首选的构造类型示例。
标签: r performance if-statement