问题是:为什么不(显式地)更快或更好地调用return,从而更可取?
R文档中没有做这样假设的语句。
主页?'function'说:
function( arglist ) expr
return(value)
不调用return会更快吗?
function()和return()都是基本函数,即使不包括return()函数,function()本身也会返回上一次求值。
将return()作为. primitive ('return')调用,并将最后一个值作为参数将完成相同的工作,但需要多调用一次。因此这个(通常)不必要的. primitive ('return')调用可以获取额外的资源。
然而,简单的测量表明所产生的差异非常小,因此不能成为不使用显式回报的原因。下图是用这种方法选择的数据绘制的:
bench_nor2 <- function(x,repeats) { system.time(rep(
# without explicit return
(function(x) vector(length=x,mode="numeric"))(x)
,repeats)) }
bench_ret2 <- function(x,repeats) { system.time(rep(
# with explicit return
(function(x) return(vector(length=x,mode="numeric")))(x)
,repeats)) }
maxlen <- 1000
reps <- 10000
along <- seq(from=1,to=maxlen,by=5)
ret <- sapply(along,FUN=bench_ret2,repeats=reps)
nor <- sapply(along,FUN=bench_nor2,repeats=reps)
res <- data.frame(N=along,ELAPSED_RET=ret["elapsed",],ELAPSED_NOR=nor["elapsed",])
# res object is then visualized
# R version 2.15
上面的图片在你的平台上可能略有不同。
根据测量的数据,返回对象的大小没有造成任何差异,重复的次数(即使缩放)只产生非常小的差异,这在真实的数据和真实的算法中无法计算或使您的脚本运行得更快。
不调用return会更好吗?
Return是一个很好的工具,可以清晰地设计代码的“叶子”,在这里例程应该结束,跳出函数并返回值。
# here without calling .Primitive('return')
> (function() {10;20;30;40})()
[1] 40
# here with .Primitive('return')
> (function() {10;20;30;40;return(40)})()
[1] 40
# here return terminates flow
> (function() {10;20;return();30;40})()
NULL
> (function() {10;20;return(25);30;40})()
[1] 25
>
这取决于程序员的策略和编程风格,他使用什么风格,他可以不使用return(),因为它不是必需的。
R核心程序员使用这两种方法。使用或不使用显式return(),因为可以在'base'函数的源中找到。
很多时候只使用return()(无参数)返回NULL来有条件地停止函数。
不清楚它是否更好,因为使用R的标准用户或分析师无法看到真正的区别。
我的观点是这个问题应该是:使用来自R实现的显式返回是否有危险?
或者,更好的是,编写函数代码的用户应该总是问:在函数代码中不使用显式返回(或将要返回的对象作为代码分支的最后一个叶)会有什么影响?