Frage

Warum verwenden würde eine Sprache nicht Kurzschlussauswertung ? Gibt es irgendwelche Vorteile der Verwendung von nicht wahr?

Ich sehe, dass es zu einigen Aufführungen Problemen führen könnte ... ist das wahr? Warum?


Verwandte Frage: Vorteile von Kurzauswertung mit

War es hilfreich?

Lösung

Gründe NICHT Kurzauswertung zu verwenden:

  1. Weil es anders verhalten und zu unterschiedlichen Ergebnissen führen, wenn Ihre Funktionen, Eigenschaft Ermittelt oder Operator Methoden haben Nebenwirkungen. A) Sprache Standards, B) vorherige Versionen Ihrer Sprache oder C) die Standardannahmen Ihrer Sprachen typische Benutzer: Und das kann in Konflikt geraten. Dies sind die Gründe, die VB hat für nicht Kurzschlüsse.

  2. Da Sie die Compiler möchten die Freiheit haben, neu zu ordnen und zu beschneiden Ausdrücke, Operatoren und Unterausdrücke, wie es für richtig hält, und nicht in der Reihenfolge, die der Benutzer eingegeben sie in. Dies sind die Gründe, dass SQL hat für nicht Kurzschluss (oder zumindest nicht in der Art und Weise, dass die meisten Entwickler zu SQL denken es kommen würde). So SQL (und einige andere Sprachen) können Kurzschluss, aber nur, wenn sie entscheiden, und nicht unbedingt in der Reihenfolge, die Sie implizit angegeben.

Ich gehe davon aus hier, dass Sie fragen nach „Automatik, impliziter auftragsspezifische Kurzschluss“, das ist, was die meisten Entwickler erwarten von C, C ++, C #, Java, usw. Sowohl VB und SQL Wegen müssen explizit < em> Kraft auftragsspezifische Kurzschlüsse. Allerdings, in der Regel, wenn die Menschen diese Frage stellen, es ist ein „Do What I Meant“ Frage; das heißt, sie bedeuten „warum es nicht tun, was ich will?“, wie in, automatisch Kurzschluss in der Reihenfolge, dass ich es geschrieben hätte.

Andere Tipps

Ein Vorteil, den ich denken kann, ist, dass einige Operationen Nebenwirkungen haben könnte, dass Sie passieren könnte erwarten.

Beispiel:

if (true || someBooleanFunctionWithSideEffect()) {
    ...
}

Aber das ist in der Regel verpönt.

Ada tut es nicht standardmäßig aktiviert. Um Kurzschlussauswertung zu erzwingen, müssen Sie and then oder or else statt and oder or verwenden.

Das Problem ist, dass es einige Situationen, in denen es die Dinge tatsächlich verlangsamt. Wenn die zweite Bedingung schnell zu berechnen und die erste Bedingung ist fast immer wahr für „und“ oder falsch für „oder“, dann ist der zusätzliche Check-Verzweigungsbefehl ist ein bisschen eine Verschwendung. Aber ich verstehe, dass mit modernen Prozessoren mit Verzweigungsvorhersager, das ist nicht so sehr der Fall. Ein weiteres Problem ist, dass die Compiler wissen passieren können, dass die zweite die Hälfte billiger ist oder wahrscheinlich zum Scheitern verurteilt, und mag die Prüfung entsprechend neu zu ordnen (was es nicht tun kann, wenn Kurzschlussverhalten definiert ist ).

Ich habe Einwände gehört, dass es zu einem unerwarteten Verhalten des Codes in dem Fall führen kann, wo die zweiten Testnebenwirkungen haben. IMHO es nur „unerwartet“ ist, wenn Sie wissen sehr gut, nicht Ihre Sprache, aber einige werden dies argumentieren.

Falls Sie interessiert sind, in welcher tatsächlichen Sprache Designer haben über dieses Thema zu sagen, hier ist ein Auszug aus dem Ada 83 (Originalsprache) Rationale :

  

Die Operanden eines Booleschen Ausdruck   wie A und B kann in ausgewertet werden   beliebiger Reihenfolge. Je nach Komplexität   der Begriff B, kann es sein,   effizient (auf einige, aber nicht alle   Maschinen) zu bewerten, wenn die B nur   Term A hat den Wert TRUE. Diese   jedoch ist eine Entscheidung Optimierung   vom Compiler genommen und es wäre   falsch, dass dies zu übernehmen   Optimierung ist immer getan. In anderen   Situationen, die wir möchten ein auszudrücken   Verbindung von Bedingungen, wobei jeder   Bedingung sollte bewertet werden (hat   Bedeutung) nur dann, wenn die vorherige   Bedingung erfüllt ist. Beide   Dinge können mit Kurzschluss erfolgen   Steuerformulare ...

     

In Algol 60 kann man den Effekt erzielen   Kurzschluss Auswertung nur durch   Verwendung von bedingten Ausdrücken, da   komplette Auswertung erfolgt   Andernfalls. Dies führt oft zu   Konstrukte, die mühsam zu folgen ...

     

Mehrere Sprachen definieren nicht wie   boolean Bedingungen sein   bewertet. Als Folge Programme   basierend auf der Bewertung Kurzschluss wird   nicht tragbar sein. Dies zeigt deutlich   verdeutlicht die Notwendigkeit zu trennen   Boolesche Operatoren von Kurzschluss   Steuerformulare.

Sehen Sie in meinem Beispiel unter Auf rel="nofollow SQL Server booleschen Operator Kurzschluss , die zeigt, warum eine bestimmte Zugriffspfad in SQL effizienter ist, wenn boolean Kurzschluss nicht verwendet. Mein Blog Beispiel zeigt es, wie eigentlich auf boolean Kurzschluss verlassen kann Ihren Code brechen, wenn Sie in SQL Kurzschluss übernehmen, aber wenn man die Argumentation lesen Warum ist SQL die rechte Seite Auswertung zuerst, Sie werden sehen, das ist richtig, und dieses Ergebnis in einem deutlich verbesserten Zugriffspfad.

Bill hat einen triftigen Grund nicht erwähnt Kurzschließen zu verwenden, aber es genauer zu formulieren. Hochparallele Architekturen manchmal Problem haben mit Pfaden Steuer Verzweigung

Nehmen Sie NVIDIAs CUDA-Architektur zum Beispiel. Die Grafikchips verwenden, um eine SIMT Architektur, die bedeutet, dass der gleiche Code auf vielen parallelen Fäden ausgeführt wird. Dies ist jedoch nur funktioniert, wenn alle Threads die gleiche bedingte Verzweigung jedes Mal nehmen. Wenn verschiedene Threads unterschiedliche Codepfade nehmen, Auswertung serialisiert -. Das bedeutet, dass der Vorteil der Parallelisierung verloren, weil einige der Fäden müssen warten , während andere führen den alternativen Code Zweig

Kurzschlüsse beinhalten den Code tatsächlich Verzweigung so Kurzschluss Operationen auf SIMT Architekturen wie CUDA schädlich sein können.

- Aber wie Bill sagte, das ist eine Hardware-Betrachtung. Soweit Sprachen gehen, ich Ihre Frage mit einem klaren beantworten würde nicht . Hat einen Kurzschluss zu verhindern nicht Sinn machen

würde ich sagen, in 99 von 100 würde ich die Kurzschlüsse Betreiber für die Leistung bevorzugen.

Aber es gibt zwei große Gründe, warum ich gefunden habe, wo ich sie nicht verwenden. (Übrigens, meine Beispiele sind in C, wo && und || sind Kurzschlüsse und & und |. Nicht)

1.) Wenn Sie zwei anrufen mögen oder mehr Funktionen in einer if-Anweisung, unabhängig vom Wert der ersten zurückgegeben.

if (isABC() || isXYZ()) // short-circuiting logical operator
    //do stuff;

In diesem Fall isXYZ () wird nur aufgerufen, wenn isABC () false zurück. Sie können aber wollen isXYZ (), um ganz gleich genannt werden, was.

Also anstatt Sie dies tun:

if (isABC() | isXYZ()) // non-short-circuiting bitwise operator
    //do stuff;

2.) Wenn Sie boolean Mathe mit ganzen Zahlen sind durchführen.

myNumber = i && 8; // short-circuiting logical operator

ist nicht unbedingt das gleiche wie:

myNumber = i & 8; // non-short-circuiting bitwise operator

In dieser Situation können Sie tatsächlich unterschiedliche Ergebnisse erhalten, weil der Kurzschluss Betreiber nicht notwendigerweise den gesamten Ausdruck bewerten. Und das macht es für boolean Mathematik im Grunde nutzlos. Also in diesem Fall würde ich stattdessen den Nicht-Kurzschluss (bitweise) Operatoren verwenden.

Wie ich schon andeutete an, diese beiden Szenarien sind wirklich selten für mich. Aber Sie können für beide Arten von Operatoren realen Programmierung Gründe zu sehen gibt. Und zum Glück die meisten populären Sprachen haben heute beide. Auch hat VB.NET die AndAlso und OrElse Kurzschlüsse Operatoren. Wenn eine Sprache hat heute nicht beide ich würde sagen, dass es hinter der Zeit ist und wirklich begrenzt die Programmierer.

Wenn Sie die rechte Seite wollte ausgewertet werden:

if( x < 13 | ++y > 10 )
    printf("do something\n");

Vielleicht wollte man y, ob oder nicht erhöht werden x <13. Ein gutes Argument gegen diese Weise ist jedoch, dass die Bedingungen, ohne Nebenwirkungen zu schaffen Praxis ist in der Regel eine bessere Programmierung.

Als Strecke:

Wenn Sie eine Sprache sein Super-sicher (auf Kosten der awesomeness) wollten, würden Sie Kurzschluss eval entfernen. Wenn etwas ‚sichere‘ eine variable Menge Zeit in Anspruch nimmt geschehen, ein Angriff Timing- verwendet werden könnte, verwirren mit ihm. Kurzschluss eval Ergebnisse in Sachen unterschiedliche Zeiten unter auszuführen, damit das Loch für den Angriff stossen. In diesem Fall würde hoffentlich nicht einmal Kurzschluss eval ermöglicht hilft sicherer Algorithmen (WRT Timing-Attacken sowieso) schreiben.

Die Ada Programmiersprache beide Booleschen Operatoren, die nicht kurzgeschlossen haben (AND, OR), zu erlaubt ein Compiler zu optimieren und möglicherweise die Konstrukte parallelisieren und Operatoren mit explizitem Antrag auf Kurzschluss (AND THEN, OR ELSE), wenn das, was Wunsch des Programmierers. Der Nachteil einer solchen Dual-Säulen-Ansatz ist die Sprache ein wenig komplexer zu machen. (1000 Designentscheidungen in der gleichen genommen „wir beides tun!“ Vein eine Programmiersprache viel komplexer Gesamt machen; -)

Nicht, dass ich denke, das ist das, was in jeder Sprache ist los jetzt, aber es wäre ziemlich interessant sein, beiden Seiten zu unterschiedlichen Threads einer Operation zu füttern. Die meisten Operanden vorherbestimmt werden kann, nicht miteinander interferieren, so würden sie gute Kandidaten für die verschiedenen CPUs Gabe aus.

Diese Kins Sache Angelegenheiten auf hochparallelen CPUs, die mehrere Zweige zu bewerten neigen und ein wählen.

Hey, es ist ein bisschen weit hergeholt, aber sie fragte: „Warum sollte eine Sprache“ ... nicht „Warum eine Sprache“.

Die Sprache Luster keine Kurzschlussauswertung verwenden. In if-then-elses, beide dann und andere Zweige werden an jedem tick ausgewertet, und man wird das Ergebnis der bedingten Abhängigkeit von der Auswertung der Bedingung betrachtet.

Der Grund dafür ist, dass diese Sprache und andere synchrone Datenfluß Sprachen, haben eine kurze Syntax der Vergangenheit zu sprechen. Jeder Zweig muss berechnet werden, so dass die Vergangenheit von jedem zur Verfügung, wenn es in Zukunft Zyklus notwendig wird. Die Sprache soll funktional sein, so dass keine Rolle würde, aber Sie können von ihm C-Funktionen aufrufen (und vielleicht bemerken, dass sie häufiger genannt werden, als Sie dachten).

In Luster, schreibt das Äquivalent von

if (y <> 0) then 100/y else 100

ist ein typischer Anfängerfehler. Die Division durch Null ist nicht zu vermeiden, weil der Ausdruck 100 / y sogar auf Zyklen ausgewertet wird, wenn y = 0.

Da Kurzschluss kann das Verhalten einer Anwendung IE ändern:

if(!SomeMethodThatChangesState() || !SomeOtherMethodThatChangesState())

Ich würde sagen, dass es für die Lesbarkeit Probleme gültig ist; wenn jemand Vorteil von Kurzschlussauswertung in einer nicht ganz offensichtlichen Weise nimmt, kann es schwierig sein, ein Betreuer auf dem gleichen Code zu suchen und die Logik verstehen.

Wenn der Speicher dient, liefert erlang zwei Konstrukte, Standard- und / oder, dann andalso / orelse. Damit wird klar gestellt, dass die Absicht, ‚Ja, ich weiß, das Kurzschließen ist, und Sie sollten auch‘, wo, wie an anderen Stellen die Absicht von Code abgeleitet werden muss.

Als Beispiel sagen, ein Betreuer über diese Zeilen kommt:

if(user.inDatabase() || user.insertInDatabase()) 
    user.DoCoolStuff();

Es dauert einige Sekunden, zu erkennen, dass die Absicht ist, „wenn der Benutzer nicht in der Datenbank ist, legen Sie ihn / sie / es, ob das funktioniert coole Sachen zu tun“.

Wie andere haben darauf hingewiesen, das ist wirklich nur dann relevant, wenn die Dinge mit Nebenwirkungen zu tun.

Ich weiß nicht, über alle Performance-Probleme, aber eine mögliche Argumentation sie (oder zumindest ein übermäßigen Gebrauch davon) zu vermeiden, ist, dass es kann andere Entwickler verwirren.

Es gibt bereits große Antworten über den Nebeneffekt Frage, aber ich habe nichts über die Leistung Aspekt der Frage sehen.

Wenn Sie keine Kurzauswertung ermöglichen, ist das Performance-Problem, dass beide Seiten noch ausgewertet werden müssen, obwohl es nicht das Ergebnis ändern. Dies ist in der Regel kein Thema, kann aber unter einem dieser beiden Umständen relevant werden:

  • Der Code ist in einer inneren Schleife, die sehr häufig genannt wird,
  • Es gibt einen hochen Kosten im Zusammenhang mit dem Auswerten von Ausdrücken (vielleicht IO oder eine teuere Berechnung)

Die Kurzschluss Auswertung liefert automatisch bedingte Auswertung eines Teils des Ausdrucks.

Der Hauptvorteil ist, dass es den Ausdruck vereinfacht.

Die Leistung verbessert werden könnte, aber man könnte auch eine Strafe für sehr einfache Ausdrücke beobachten.

Eine weitere Folge ist, dass die Nebenwirkungen der Auswertung des Ausdrucks betroffen sein könnte.

In der Regel auf Nebeneffekt angewiesen ist keine gute Praxis, aber in einigem spezifischen Zusammenhang könnte es die bevorzugte Lösung sein.

VB6 nicht kurzschluss Auswertung nicht verwendet, ich weiß nicht, ob neuere Versionen zu tun, aber ich bezweifle es. Ich glaube, das ist nur, weil ältere Versionen auch nicht getan haben, und weil die meisten der Menschen, die VB6 verwendet würde nicht erwarten, dass das geschehen kann, und es würde zu Verwirrung führen.

Dies ist nur eines der Dinge, die es extrem schwer gemacht für mich zu bekommen von einem noob VB Programmierer zu sein, den Spaghetti-Code geschrieben hat, und mit meiner Reise bekommen auf einen real Programmierer zu sein.

Viele Antworten werden über Nebenwirkungen gesprochen. Hier ist ein Python-Beispiel ohne Nebenwirkungen, in der (meiner Meinung nach) einem Kurzschluss Lesbarkeit verbessert.

for i in range(len(myarray)):
  if myarray[i]>5 or (i>0 and myarray[i-1]>5):
    print "At index",i,"either arr[i] or arr[i-1] is big"

Der Kurzschluss garantiert, dass wir nicht versuchen, myarray zuzugreifen [-1], die eine Ausnahme auslösen würden, da Python-Arrays auf 0. Der Code könnte natürlich von starten, ohne Kurzschlüsse geschrieben werden, z.

for i in range(len(myarray)):
  if myarray[i]<=5: continue
  if i==0: continue
  if myarray[i-1]<=5: continue
  print "At index",i,...

, aber ich denke, dass der Kurzschluss Version mehr lesbar ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top