1. ホーム
  2. r

[解決済み】関数内でreturnを明示的に呼び出すかどうか

2022-04-08 10:22:34

質問

しばらく前に 叱られた を明示的に呼び出すことを推奨したことについて、R コアチームの Simon Urbanek (だったと思います) から指摘されました。 return を関数の末尾に追加しました(彼のコメントは削除されましたが)。

foo = function() {
  return(value)
}

と薦めた。

foo = function() {
  value
}

おそらく、このような状況では必要なのでしょう。

foo = function() {
 if(a) {
   return(a)
 } else {
   return(b)
 }
}

彼のコメントから、なぜ電話をかけないのかが見えてきました。 return しかし、これは削除されました。

私の疑問は、なぜ return より速く、より良く、そしてより望ましいのでしょうか?

どのように解決するのですか?

疑問がありました。なぜ(明示的に)returnを呼び出さない方が速いのか、良いのか、つまり望ましいのか?

Rのドキュメントには、そのような仮定をする記述はありません。

メインページ ?function'に書いてあります。

function( arglist ) expr
return(value)

returnを呼ばない方が速い?

両方 function()return() はプリミティブ関数であり function() を含まなくても、それ自体が最後に評価された値を返します。 return() 関数を使用します。

呼び出し return() として .Primitive('return') のように、最後の値を引数として指定しても、同じ処理を行いますが、1回多く呼び出す必要があります。 そのため、この(しばしば)不要な .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()を明示的に使う場合と使わない場合の両方のアプローチを使っています。

多くの場合、return()のみが使用され(引数なし)、条件付きで関数を停止させる場合はNULLを返します。

Rを使う標準的なユーザーやアナリストには、この違いが分からないので、良いのか悪いのかよく分からない。

私の意見は、質問はこうあるべきだということです。 Rの実装から来る明示的な戻り値を使用することに危険はないのか?

あるいは、関数コードを書いているユーザーは、常に質問するようにしたほうがいいかもしれない。 にはどのような効果があるのでしょうか? ではなく 関数コードの中で明示的に return を使用する (またはコード分岐の最後の葉に return されるオブジェクトを配置する) ことは可能ですか?