web-dev-qa-db-ja.com

if-return-returnまたはif-else-returnを使用する方が効率的ですか?

ifを含むreturnステートメントがあるとします。効率の観点から、私は使用する必要があります

if(A > B):
    return A+1
return A-1

または

if(A > B):
    return A+1
else:
    return A-1

コンパイルされた言語(C)またはスクリプト化された言語(Python)を使用する場合、どちらを優先すべきですか?

105
Jorge Leitão

returnステートメントは現在の関数の実行を終了するため、2つの形式は同等です(ただし、2番目の形式は最初の形式よりも間違いなく読みやすいです)。

両方の形式の効率は同等であり、if条件がいずれにせよ偽である場合、基礎となるマシンコードはジャンプを実行する必要があります。

Pythonは、ケースでreturnステートメントを1つだけ使用できる構文をサポートしていることに注意してください。

return A+1 if A > B else A-1
143

Chromium's スタイルガイドから:

復帰後にelseを使用しないでください:

# Bad
if (foo)
  return 1
else
  return 2

# Good
if (foo)
  return 1
return 2

return 1 if foo else 2
27
skeller88

コーディングスタイルについて:

ほとんどのコーディング標準は、言語に関係なく、単一の関数からの複数のreturnステートメントを悪い習慣として禁止しています。

(個人的には、複数のreturnステートメントが意味をなすいくつかのケースがあると言います:テキスト/データプロトコルパーサー、広範なエラー処理機能など​​)

これらのすべての業界コーディング標準からのコンセンサスは、式を次のように記述する必要があるということです。

int result;

if(A > B)
{
  result = A+1;
}
else
{
  result = A-1;
}
return result;

効率について:

上記の例と問題の2つの例は、効率の点ですべて完全に同等です。これらすべての場合のマシンコードは、A> Bを比較し、A + 1またはA-1計算に分岐し、その結果をCPUレジスタまたはスタックに保存する必要があります。

編集:

ソース:

  • MISRA-C:2004ルール14.7では、次のように引用しています...:
  • IEC 61508-3。パート3、表B.9。
  • IEC 61508-7。 C.2.9。
5
Lundin

賢明なコンパイラーであれば、違いは観察しないでください。それらは同等であるため、同一のマシンコードにコンパイルする必要があります。

3

バージョンAの方が簡単なので、それを使用します。

また、Javaですべてのコンパイラ警告をオンにすると、2番目のバージョンで警告が表示されます。これは不要であり、コードの複雑さが増すためです。

1
juergen d

個人的にはelseブロックを可能な限り避けています。 Anti-ifキャンペーン を参照してください

また、彼らはラインのために「余分な」を請求しません、あなたは知っています:p

「単純なものは複雑なものより優れている」 &「読みやすさが重要」

delta = 1 if (A > B) else -1
return A + delta
1
percebus

私は質問がpythonでタグ付けされていることを知っていますが、動的言語について言及しているので、Rubyでifステートメントが実際に戻り値の型を持っているので、

def foo
  rv = if (A > B)
         A+1
       else
         A-1
       end
  return rv 
end

または、単純に暗黙の戻り値もあるため

def foo 
  if (A>B)
    A+1
  else 
    A-1
  end
end

これは、複数のリターンをうまく持たないというスタイルの問題を回避します。

0
Jamie Cook

次のように考えてください:

if (a > b):
    output = a + 1

output = a - 1

return output

対これ:

if (a > b):
    output = a + 1
else:
    output = a - 1

return output

最初の例は機能しませんが、2番目の例は正常に機能します。これらのパフォーマンスは同じであるため、私の意見では読みやすいため、例2を使用することをお勧めします。

0
Juniorized