10
boolean a = false, b = true;
if ( a && b ) { ... };

ほとんどの言語では、はfalseであるためb評価されないため、trueにはなりません。私の質問は、アーキテクチャの観点から短絡が遅くなるのではないかということです。パイプラインでは、bを評価する必要があるかどうかを判断するために、aの結果を取得するのを待っている間、ストールしますか?代わりにネストされたifを実行する方が良いでしょうか?それも役に立ちますか?aa && b

また、誰もが一般的にどのような短絡評価と呼ばれるか知っていますか?この質問は、プログラミングの友人が短絡評価について聞いたことがなく、それは一般的ではなく、多くの言語で見られず、パイプラインでは非効率的であると述べた後に発生しました。最後のものはよくわかりませんので、よろしくお願いします!

さて、私はおそらく私の友人がどこから来ているのかを説明する別の例だと思います。彼は、次のようなステートメントを並行して評価して以来、次のように信じています。

(a) if ( ( a != null ) && ( a.equals(b) ) ) { ... }

システムがクラッシュします。短絡がない(したがって、上記のようなステートメントを許可しない)アーキテクチャでは、次のようなステートメントの処理が高速になります。

(b) if ( ( a == 4 ) && ( b == 5 ) )

(a)並列に実行できなかった場合、(b)並列に実行できないためです。この場合、短絡を許可する言語は、短絡を許可しない言語よりも低速です。

それが本当かどうかはわかりません。

ありがとう

4

15 に答える 15

12

短絡評価は、ステートメントがifステートメントの場合と同じ方法でアセンブリ言語のブランチに変換されます(ブランチは基本的にgotoです)。つまり、ifステートメントよりも遅くなることはありません。

ブランチは通常、パイプラインストールを停止しませんが、プロセッサはブランチが取得されたかどうかを推測します。プロセッサが間違っている場合は、パイプラから間違った推測を行ったために発生したすべてをフラッシュする必要があります。

短絡評価もその最も一般的な名前であり、ほとんどの言語で何らかの形で見られます。

于 2008-09-18T01:24:48.553 に答える
10

短絡ブール式は、ネストされた if のセットとまったく同じであるため、それと同じくらい効率的です。

b に副作用がない場合でも、a と並列に実行できます (パイプライン処理を含む「並列」の任意の値に対して)。

b に、分岐予測が失敗したときに CPU アーキテクチャがキャンセルできない副作用がある場合は、はい。これには、両方の側が常に評価される場合には存在しない遅延が必要になる可能性があります。したがって、ショートサーキット演算子がコードでパフォーマンスのボトルネックを作成していることに気付いた場合は、これを確認する必要がありますが、それ以外の場合は心配する必要はありません。

しかし、不必要な作業を省くために、短絡は制御フローに使用されます。これは、私が使用した言語間で共通しています。たとえば、Perl の慣用句は次のとおりです。

open($filename) or die("couldn't open file");

シェルのイディオム:

do_something || echo "that failed"

または C/C++/Java/etc のイディオム:

if ((obj != 0) && (obj->ready)) { do_something; } // not -> in Java of course.

これらのすべての場合で、短絡が必要です。そのため、RHS は、LHS がそうすべきであると指示した場合にのみ評価されます。そのような場合、間違った代替コードとパフォーマンスを比較しても意味がありません!

于 2008-09-18T01:55:13.143 に答える
8

正直心配しません。ブール値のテストは非常に高速です。短絡は、2番目の式に副作用がある場合にのみ興味深い/有用になります。

if ( ConfirmAction() && DestroyAllData() )
   Reboot();

...または最初のテストに依存します:

if ( myDodgyVar != null && myDodgyVar.IsActive() )
   DoSomethingWith(myDodgyVar);
于 2008-09-18T01:25:43.543 に答える
5

ショートサーキットをサポートする言語:

Ada、Eiffel、ALGOL 68、C1、C++、C#、Java、R、Erlang、標準 ML、Javascript、MATLAB、Lisp、Lua、Scheme、OCaml、Haskell、Pascal、Perl、Ruby、PHP、Python、Smalltalk、Visual Basic 。ネット

短絡評価より抜粋

于 2009-06-21T19:00:09.167 に答える
3

VB.Net の構文は、短絡するかどうかによって異なります。従来の理由により、デフォルトの動作は短絡しないことです。構文は次のとおりです。

非短絡

IF A And B THEN
    ...
END IF

短絡

IF A AndAlso B THEN
    ...
END IF

OR ステートメントを省略したい場合は、Or / OrElse を使用できます。次のような状況で本当にいいです

If MyObj IsNot Nothing AndAlso MyObj.Value < SomeValue Then
    ....
End If

個人的には、短絡が高速化できることは理解していますが、コードを見ただけでは明らかなことではありません。経験の浅い開発者がこの振る舞いに混乱しているのを見ることができました。最適化レベルのコンパイラフラグに応じて、発生する可能性があるかどうかのようにさえ思えます。実際に達成したい動作について VB がどのように冗長であるかが気に入っています。

于 2008-09-18T01:36:56.887 に答える
2

まず、あなたの友達は間違っています。短絡評価(別名最小評価)はほとんどの言語で利用可能であり、並列言語のネストされたifよりも優れています(この場合、返される最初の条件によって実行が続行されます)

いずれにせよ、単純な非並列言語であっても、最初の条件が評価されるまで実行がブロックされるため、ネストされたifがどのように高速になるかはわかりません。

于 2008-09-18T01:27:23.257 に答える
1

ストールしない場合、どのようにネストできますか?実際、aとbが両方とも変数であり、副作用のある式ではない場合、優れたコンパイラーによって並列にロードできます。行数を増やす以外に、より多くのifを使用するメリットはありません。本当に、これはコンパイラを推測する最悪の種類です。

これは短絡評価と呼ばれます。

于 2008-09-18T01:23:54.547 に答える
1

私が使用する便利な短絡は次のようなものです。

if (a != null && a.equals(somevalue)) {
    ... do something.
}

これは、私の意見では非常に読みやすく、非常にうまく機能します。一般的に、私はあまりにも多くのネストを避けようとします。それは醜いコードにつながるからです。

私の意見はすべて。

于 2008-09-18T01:25:44.823 に答える
1

ほとんどの言語は、ブール式の短絡評価を行います。私はいつもそれが短絡評価と呼ばれるのを聞いたことがあります。

質問の例は非常に単純な例であり、パフォーマンス上の利点はあまりありません。パフォーマンス上の利点は、式の評価が複雑な場合に発生します。

これが良い場合の例として、次のようなゲームプログラムを想像してみてください。

if (someObject.isActive() && someOtherObject.isActive() && CollisionDetection.collides(someObject, someOtherObject) {
  doSomething();
}

この場合、衝突検出はアクティブチェックよりもはるかにコストがかかります。システムに非アクティブなオブジェクトが多数ある場合は、パフォーマンスが大幅に向上します。

于 2008-09-18T01:25:51.030 に答える
1

短絡が効率的かどうかに関しては、パイプライン化がパフォーマンスに大きな影響を与える可能性は低いです。影響を与える可能性がある状況では、これらのテストに副作用がない限り、コンパイラが複数の条件を並行してテストするのを止めるものは何もありません。さらに、最新の CPU には、分岐コードのパイプライン パフォーマンスを向上させるのに役立ついくつかのメカニズムがあります。

ネストされた if は、&& をショートサーキットするのと同じ効果があります。

「短絡評価」はその最も一般的な名前であり、あなたの友人はそれが珍しいことについて間違っています。それは非常に一般的です。

于 2008-09-18T01:34:51.773 に答える
1

ショートサーキットまたは最小限の評価は、ネストされた if の構文糖衣にすぎません。それが非効率的である、またはストールを引き起こすと仮定することは、時期尚早の最適化のケースです。この時点で、ほとんどのコンパイラは、これらのステートメントを正しく解釈して最適化するのに十分なほどインテリジェントです。これらのステートメントを使用すると、ネストが大幅に削減されるため、コードの可読性が向上します。これが最大の目標です。

于 2008-09-18T01:29:03.143 に答える
0

状況によっては、「保護」と呼ばれることもあります。

そして、私がこれまでに取り組んだほぼすべての言語でそれを見てきました。

于 2008-09-18T01:24:35.230 に答える
0

パイプラインについては何も知りませんが、短絡評価は多くの言語に共通の機能です(これは私が知っている名前でもあります)。Cでは、&&と他の演算子は、;と同じようにシーケンスポイントを定義します。演算子はそうするので、複数のステートメントを使用するよりも短絡評価の効率がどれほど低いかはわかりません。

于 2008-09-18T01:26:11.373 に答える
0

私はそれを短絡として聞いただけです。パイプラインでは、次の操作はifステートメントの結果に依存しませんか?その場合、これはより最適化されるため、毎回2つの値をテストする必要はありません。

于 2008-09-18T01:28:10.230 に答える
0

単一のスレッドはシーケンシャルであるため、2 つの if がある場合、もちろん最初のものが 2 番目の前に評価されるため、違いはわかりません。私は条件付き AND 演算子 (これは && が afaik と呼ばれるものです) をネストされた if よりもはるかに多く使用します。評価に時間がかかる可能性のあるものをチェックしたい場合は、最初に簡単なテストを行い、条件付き and の後に難しいテストを行います。

a = obj.somethingQuickToTest() && obj.somethingSlowToTest();

と何ら変わらないようです

a = false;
if(obj.somethingQuickToTest())
   a = obj.somethingSlowToTest();

于 2008-09-18T01:31:10.330 に答える