短絡評価が悪いのはいつですか?


12

もう少し明確にするために、私はさまざまな言語で多くの時間を費やしたと述べます。しかし、これまでは常に使用するか、まったくサポートしていませんでした。

現在、VB.netを必要とするプロジェクトで作業を開始していますが、ANDANDALSOの両方の面でVB.netを提供しているようです。最初のものは短絡せず、2番目のものは短絡します。

だから、これはなぜだろうかと思いますか?このように設定すると、モードを切り替えたいことが頻繁に発生することを暗示しているようです。しかし、短絡回路を使用することが悪いことになるような状況は考えられません。

私はこれがより多くのオプションのものに入る可能性があることを知っているので、これを他の場所に置く必要がある場合は、どこにいるか教えてください。

私は少なくとも公式の答えがあればいいのにと思っていますが、両方のオプションがあるのは、可能な場合は常にShort Circuitを行うよりも良い理由についてです。



回答:


5

論理式の一部の用語には、副作用がある場合があります。すべての副作用が指定された順序で発生することを保証することが必要な場合があり、スキップされないものがあり、論理を導くのは評価結果です。

if not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

それ以外の場合、以前の評価でfalseが返された場合、残りの用語を評価したくない場合があります。

if IsAirborne() and not (PushAirPlane(thrust) and TurnAirplane(vector)), SimulateCrash(severity)

2番目の例の短絡動作に依存するのは悪い形式であると主張する人もいますが、それはコーディングスタイルと信念体系になりつつあります。世界には、言語が提供するほぼすべての機能に依存する非常に優れたコードが数多くありますが、それはまさにその通りです。

VBのANDALSOは鮮明で、練習をより受け入れやすくする試みのようです。

JimmyJamesが彼の答えで指摘しているように、短絡評価に関して測定可能なパフォーマンスへの影響がある可能性があります。メカニズムを提供しない言語は、常に式のすべての用語を評価しますが、提供する言語は追加の分岐ステートメントを生成できます。どちらの場合も、各用語を評価するために必要な処理ステップの数と、コンパイラーおよびCPUアーキテクチャーに大きく依存します。通常、コードにボトルネックが測定され、それを軽減する方法を見つけるまで、そのようなことは気にしません。コードで短絡評価を許可するかどうかのルールは、コードを遅くし、早期に最適化することは時間の無駄になる可能性があるため、常に測定してから最適化することができます。


4
事実正しいが、それは素晴らしいデザインではありません。
ロバートハーヴェイ

2
@RobertHarvey、副作用のない制御システムを書くことはできず、結果に反応しないとシステムを正しく制御できません。言い換えれば、それを乗り越えます;)。
jwdonahue

7
いいえ。ただし、これらの副作用関数の結果をブール変数に割り当て、if条件内の変数を確認しながら、短絡させることができます。ある意味、文体的な区別であることに同意しますが、物事を明確にするという美徳があります。
ロバートハーヴェイ

3
@jwdonahue混乱のリスクが低い場合は、「大きな単語」を使用しても構いません。このようなコードブロックの混乱や特定のニュアンスの欠落のリスクは非常に高く、ロジックに壊滅的な影響を与える可能性があります。読書開発者に非常に一生懸命に考えさせることは決して良くありません。
jpmc26

5
「論理式の一部の用語には副作用がある可能性があります」-この冒頭の文は正しいものの、副作用に頼ることが悪いことを指摘していないため、この答えは失敗すると感じています。実際、偽の評価を防ぐために短絡評価に頼るよりもはるかに悪い。この答えが示唆するものは、悪い形かもしれません。
アロス

20

どうやら、あなたの質問は、短絡が一般的に良いか悪いかということではなく、VB.NETがそれを使用する場合と使用しない場合にオペレーターに提供する理由に関するものです。これを念頭に置いて、への答え

短絡評価はいつ悪いですか?

単に:後方互換性に違反する場合。

さて、VB.NETは古いVB6やVBAとの下位互換性はあまりないと言えますが、少なくとも言語の特定の部分は互換性があります。古いANDおよびORのセマンティクスを(短絡なしで)維持するというMicrosoftの決定により、古いVBプログラムをVB.NETに移植する際にエラーの大きなカテゴリが発生する可能性が低くなりました。

一方、VB.NETの言語設計者は、おそらく短絡は良いことだという意見を共有しました。正しく覚えていると、最初のVB.NETプレリリースバージョンはANDまたはOR演算子に短絡を提供していましたが、開発者のフィードバックは非常に悪く、VB.NET 1.0が登場する前にこの決定を取り下げたに違いありません。デザイナーが新しいキーワードの面でそれを実装することを決めたので、ANDALSOORELSEの後方互換性と有用性とのトレードオフとして。

私見これは良い決断でした。過去10年間にいくつかの古いプログラムを移植する必要がありましたが、ANDおよび/またはOR(しゃれを目的とする)を含むすべての論理式に対して重い影響分析を行う必要がなかったため、そのタスクははるかに簡単で経済的になりました。一方、VB.NETで新しい論理式を記述する必要があるときはいつでも、演算子のデフォルトの選択は短絡形式です。これは、C、C ++、C#などから慣れているものです。いくつかのイディオムをより簡潔な形式で記述します(ANDALSOでさらに4文字入力する必要がある場合でも)。

納得できない場合は、Joel SpolskyのMartian Headsetsに関する素晴らしい記事をお読みになることをお勧めします。これは、コンポーネントまたは言語またはステークのAPIが特定のサイズのユーザーベースに達した後、ソフトウェア開発の初期設計決定を簡単に取り消せない理由に関するものです。


わかりました、これは暴言として資格があり、火星のヘッドセットへのリンクはまったく関連していないようです。
jwdonahue

6
@jwdonahue:どうしてこれが暴言だと思うのか、まったく逆です。そして、Martian Headsetsに関する記事は、数十年前に行われたソフトウェア開発の設計決定の一部が、対象のコンポーネントまたは言語またはAPIが特定のサイズのユーザーベースに達した後、簡単に取り消せない理由に関するものです。類推を理解するのは本当に難しいことではありませんか?VB6は過去に非常に人気があり、世界中の何十万もの企業がVB6またはVBAで実行されるミッションクリティカルなアプリを持っていると確信しています。
ドックブラウン

「火星の最前線」の記事が実際にどのように適合するのか、私にはよくわかりません。XとYの間の相互運用性(ナットとボルトなど)を確保するために必要なのは、XとYに別々の標準を設け、最悪の場合のナットが指定よりわずかに悪いボルトに対応できるようにすることです。ナットやボルトを不必要に高価にしたり、ナットとボルトの間に不必要な量の傾斜を作ったりすることを避けるために、仕様を記述してみてください。両方に役立つ。
supercat

3
@supercat:これは、すでに数兆個のナット(またはVB6コードの行)が存在し、使用されていることに関するものであり、ボルト(この場合はVBコンパイラー)は新しい世代に置き換えられます。既存のナットが非メトリックボルトのみに適合する場合、新しいボルトをメトリックシステムのみにすることは経済的ではありません。
ドックブラウン

tl; dr:VBは、1964年以降の言語であるBASICの方言であり、BASICではAnd操作は短絡せず、SQL(1974)、FORTRAN(1956)、Pascal(1970)でも短絡しません。
ベン

3

短絡評価はいつ悪いのですか?

ブール値の全体的な結果の評価で実行されると予想される式の副作用に依存し始めるとすぐに、それらは悪くなります。


1

警告:これは少し難解です。ほとんどの場合、開発者は心配する必要はありません。しかし...実行時に分岐が発生するため、条件付き評価が原因でパフォーマンスが低下する可能性があります。非短絡操作は分岐せず、より予測可能です。

これがめったに問題にならない理由は、通常、コストが小さく、通常は2番目(または3番目など)の条件を評価するコストを上回るためです。これは、高性能が必要な場合に計算負荷の高いルーチンでのみ重要であり、それでも問題ではない可能性があります。


これまでのところ、論理ステートメントのみを最適化できると思いますが、最終的には分岐を取る必要があります。
jwdonahue

@jwdonahue私はあなたのポイントを得ることができません。ごめんなさい。
ジミージェームズ

ここで組み合わせロジックについて話しています。短絡評価の有無にかかわらず、以前の用語の結果に応じて評価する必要のある1つ以上の用語があります。したがって、分岐が関係しています。
jwdonahue

1
@jwdonahueもちろん、すべての短絡は追加のブランチです。特定のシナリオでは、2番目の式が無関係である場合が多い場合でも、2つの式を実行すると(たとえば)2番目の式を実行する前に最初の式の結果をチェックするよりも高速です。繰り返しますが、これが重要になることはめったにありません。これについて誰かが私にしたケースは、行列乗算のようなもので、多くの単純な評価がある場合です。
ジミージェームズ

1
私はあなたへの信用で私の答えを更新しました。
-jwdonahue

0

パスカルは、ANDとORが短絡評価を使用するかどうかを定義しませんでした。これにより、両方の世界で最悪の事態が発生します。

CおよびC ++にはビット単位の演算&および|があります これは実際には非短絡操作を提供します。また、コンパイラーは、目に見える違いをもたらさない場合、好きな方法で評価することができます。


@Deduplicator:前述のように、Pascal AND / ORが短絡評価を使用するかどうかを定義しませんでした。それは「知らない」ことを意味します。
-supercat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.