5

2 つの条件 (OR 演算子で区切られている) を持つ if ステートメントがあります。条件の 1 つは +70% の状況をカバーし、2 番目の条件よりも処理/実行にかかる時間がはるかに短いため、速度のために、最初の条件が false と評価された場合に処理される 2 番目の条件。

最初の条件 (より速い条件) が最初に if ステートメントに現れるように条件を並べ替えると、この条件が満たされ、true と評価された場合、2 番目の条件は処理されますか?

if ( (condition1) | (condition2) ){
  // do this
}

または、最初の条件が false と評価された場合にのみ 2 番目の条件をチェックするために、2 つの if ステートメントをネストする必要がありますか?

if (condition1){
  // do this
}else if (condition2){
  // do this
}

私はPHPで作業していますが、これは言語に依存しない可能性があると思います。

4

11 に答える 11

9

C、C++、C#、Java、およびその他の .NET 言語の場合、ブール式は最適化されているため、十分な情報が得られるとすぐに他の評価は行われません。

難読化されたコードを実行するための古いトリックは、これを使用して次のような if ステートメントを作成することでした。

a || b();

「a」が真の場合、「b()」は評価されないため、次のように書き換えることができます。

if(!a)
    b();

同様に:

a && b();

になるだろう

if(a)
    b();

これは || に対してのみ有効であることに注意してください。および && 演算子。2 つの演算子 | and & はそれぞれビット単位の or、and および and であるため、「最適化」されていません。

編集: 他の人が述べたように、短絡ロジックを使用してコードを最適化しようとしても、時間をかけられることはめったにありません。

読みやすく理解しやすいため、最初に明確にする必要があります。また、あまり賢くしようとすると、用語を単純に並べ替えるだけで、明らかな理由もなく、まったく異なる動作につながる可能性があります。

次に、最適化を行いますが、タイミングとプロファイリングの後でのみ行います。あまりにも多くの開発者が、プロファイリングを行わずに時期尚早の最適化を行っています。ほとんどの場合、それはまったく役に立ちません。

于 2008-08-29T18:27:35.003 に答える
3

C、C++、および Java では、ステートメント:

if (condition1 | condition2) {
  ...
}

は両方の条件を毎回評価し、式全体が true の場合にのみ true になります。

ステートメント:


if (condition1 || condition2) {
  ...
}

が false のcondition2場合にのみ評価されます。condition1condition2 が関数または副作用のある別の式である場合、違いは顕著です。

||ただし、ケースとif/ケースに違いはありませんelse

于 2008-08-29T18:34:25.410 に答える
3

ほとんどすべての言語が短絡評価を行います。つまり、絶対に必要な場合にのみ、2 番目の条件が評価されます。これが機能するために、ほとんどの言語は単一パイプ | ではなく、二重パイプ || を使用します。

http://en.wikipedia.org/wiki/Short-circuit_evaluationを参照

于 2008-08-29T18:24:25.310 に答える
2

短絡は最適化のためではありません。主な目的は、機能しないコードを呼び出さないようにすることですが、結果として読み取り可能なテストになります。例:

if (i < array.size() && array[i]==foo) ...

iが範囲外にあり、プログラムがクラッシュした場合、array[i]がアクセス違反を起こす可能性が非常に高いことに注意してください。したがって、このプログラムは確かに評価の短絡に依存しています!

これが、最適化の問題よりもはるかに頻繁に式をこのように書く理由であると私は信じています。

于 2008-09-16T21:48:52.090 に答える
2

私は最近、この種の質問をたくさん見てきました.n次の最適化です。

特定の状況では理にかなっていると思います:

  1. 計算条件 2 は一定時間演算ではありません
  2. あなたは教育目的で厳密に求めています.3usを節約するためではなく、言語がどのように機能するかを知りたい.

他の場合では、条件を反復またはチェックする「最速」の方法を心配するのはばかげています。記録可能な (しかし重要ではない) 違いを確認するために何百万回もの試行を必要とするテストを作成する代わりに、明確さに焦点を当てます。

他の誰か (あなたかもしれません!) がこのコードを 1 か月または 1 年で理解するとき、最も重要なのは明快さです。

この場合、最初の例はより短く、より明確であり、繰り返す必要はありません。

于 2008-08-29T18:32:30.280 に答える
2

この記事によると、 PHP は短絡評価を行います。つまり、最初の条件が満たされた場合、2 番目の条件は評価されません。テストも非常に簡単です(記事から):

<?php
/* ch06ex07 – shows no output because of short circuit evaluation */

if (true || $intVal = 5) // short circuits after true
{

echo $intVal; // will be empty because the assignment never took place
}

?>
于 2008-08-29T18:32:45.273 に答える
1

最適化の目的でショートサーキットを使用することはしばしばやり過ぎですが、それを使用する他の説得力のある理由は確かにあります。そのような例の 1 つ (C++) は次のとおりです。

if( pObj != NULL && *pObj == "username" ) {
    // Do something...
}

pObjここでは、逆参照する前に確実に が割り当てられていることを確認するために、ショートサーキットに依存しています。ifこれは、ステートメントをネストするよりもはるかに簡潔です。

于 2008-08-29T22:00:55.757 に答える
0

VB.netには、「OrElse」と「AndAlso」という2つのすばらしい表現があります。

OrElseは、最初にTrue評価に到達したときにそれ自体を短絡し、必要なコードを実行します。

If FirstName = "Luke" OrElse FirstName = "Darth" Then
   Console.Writeline "Greetings Exalted One!"
End If

AndAlsoは、最初にFalse評価を行ったときにそれ自体を短絡し、ブロック内のコードを評価しません。

If FirstName = "Luke" AndAlso LastName = "Skywalker" Then
   Console.Writeline "You are the one and only."
End If

これらは両方とも役に立ちます。

于 2008-08-29T22:06:06.337 に答える
0

|、PHP のビット演算子です。正確には、という意味ではありません$a OR $b。二重管を使用する必要があります。はい、前述のとおり、PHP は短絡評価を行います。同様に、&&句の最初の条件が false と評価された場合、PHP は句の残りの部分も評価しません。

于 2008-08-29T18:45:18.737 に答える
0

まともな最適化を備えたほとんどの言語では、前者は問題なく機能します。

于 2008-08-29T18:26:30.000 に答える
0

これは言語にとらわれないタグが付けられているので、参加します。少なくとも Perl の場合は、最初のオプションで十分です。私は PHP に詳しくありません。左から右に評価され、条件が満たされるとすぐにドロップアウトします。

于 2008-08-29T18:22:35.890 に答える