不久前,因为我建议用户return在函数结束时显式调用(尽管他的评论已被删除):
return
foo = function() { return(value) }
相反,他建议:
foo = function() { value }
可能在这种情况下,它是必需的:
foo = function() { if(a) { return(a) } else { return(b) } }
他的评论阐明了为什么return除非非常需要才打电话是一件好事,但这已被删除。
我的问题是:为什么不调用return更快或更好,因此更可取?
问题是:为什么不(明确地)调用 return 更快或更好,因此更可取?
R 文档中没有声明做出这样的假设。 主页“功能”说:
function( arglist ) expr return(value)
不调用return会更快吗?
function()和都是return()原始函数,function()即使不包含函数,它本身也会返回最后的评估值return()。
function()
return()
return()将最后一个值作为参数调用.Primitive('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是一个很好的工具,可以清楚地设计例程应该结束的代码“叶子”,跳出函数并返回值。
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 >
这取决于程序员的策略和编程风格,他使用什么风格,他可以使用 no return() 因为它不是必需的。
R核心程序员使用这两种方法,即。有和没有明确的 return() 因为可以在“基本”函数的来源中找到。
很多时候,在有条件地停止函数的情况下,只使用 return()(无参数)返回 NULL。
目前尚不清楚它是否更好,因为使用 R 的标准用户或分析师看不到真正的区别。
我的观点是,问题应该是: 使用来自 R 实现的显式返回是否有任何危险?
或者,也许更好的是,编写函数代码的用户应该总是问:在函数代码 中 不 使用显式返回(或将要返回的对象作为代码分支的最后一叶)有什么影响?