Frage

Ich habe eine if-Anweisung mit zwei Bedingungen (getrennt durch einen ODER-Operator), eine der Bedingungen deckt +70 % der Situationen ab und benötigt viel weniger Zeit für die Verarbeitung/Ausführung als die zweite Bedingung, daher möchte ich aus Gründen der Geschwindigkeit nur die zweite Bedingung, die verarbeitet werden soll, wenn die erste Bedingung „falsch“ ergibt.

Wenn ich die Bedingungen so ordne, dass die erste Bedingung (die schnellere) zuerst in der if-Anweisung erscheint – wird die zweite Bedingung überhaupt verarbeitet, wenn diese Bedingung erfüllt ist und als wahr ausgewertet wird?

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

Oder müsste ich zwei if-Anweisungen verschachteln, um die zweite Bedingung nur zu überprüfen, wenn die erste als falsch ausgewertet wird?

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

Ich arbeite in PHP, gehe jedoch davon aus, dass dies sprachunabhängig sein kann.

War es hilfreich?

Lösung

Für C, C++, C#, Java und andere .NET-Sprachen werden boolesche Ausdrücke optimiert, sodass nichts anderes ausgewertet wird, sobald genügend Informationen vorliegen.

Ein alter Trick zum Erstellen von verschleiertem Code bestand darin, damit if-Anweisungen zu erstellen, wie zum Beispiel:

a || b();

Wenn „a“ wahr ist, würde „b()“ niemals ausgewertet werden, also können wir es umschreiben in:

if(!a)
    b();

und ähnlich:

a && b();

würde werden

if(a)
    b();

bitte beachten Sie dass dies nur für das || gültig ist und && Operator.Die beiden Operatoren | und & ist bitweise oder und und und sind daher nicht "optimiert".

BEARBEITEN:Wie bereits von anderen erwähnt, ist der Versuch, Code mithilfe von Kurzschlusslogik zu optimieren, sehr selten sinnvoll.

Achten Sie zunächst auf Klarheit, da es einfacher zu lesen und zu verstehen ist.Wenn Sie außerdem versuchen, zu schlau zu sein, kann eine einfache Neuordnung der Begriffe ohne ersichtlichen Grund zu völlig unterschiedlichem Verhalten führen.

Zweitens: Optimieren Sie, aber erst nach Timing und Profilerstellung.Viel zu viele Entwickler führen vorzeitige Optimierungen ohne Profilerstellung durch.Meistens ist es völlig nutzlos.

Andere Tipps

Nahezu jede Sprache führt eine Kurzschlussbewertung durch.Das bedeutet, dass die zweite Bedingung nur dann ausgewertet wird, wenn dies unbedingt erforderlich ist.Damit dies funktioniert, verwenden die meisten Sprachen die doppelte Pipe, ||, nicht die einfache Pipe, |.

Sehen http://en.wikipedia.org/wiki/Short-Circuit_evaluation

In C, C++ und Java lautet die Anweisung:

if (condition1 | condition2) {
  ...
}

wertet jedes Mal beide Bedingungen aus und ist nur dann wahr, wenn der gesamte Ausdruck wahr ist.

Die Aussage:


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

werde auswerten condition2 nur wenn condition1 ist falsch.Der Unterschied ist signifikant, wenn Bedingung2 eine Funktion oder ein anderer Ausdruck mit einer Nebenwirkung ist.

Es gibt jedoch keinen Unterschied zwischen den || Fall und die if/else Fall.

Ich habe in letzter Zeit viele Fragen dieser Art gesehen – Optimierung bis zum n-ten Grad.

Ich denke, dass es unter bestimmten Umständen sinnvoll ist:

  1. Bei der Berechnung von Bedingung 2 handelt es sich nicht um eine Operation mit konstanter Zeit
  2. Sie fragen ausschließlich zu Bildungszwecken – Sie möchten wissen, wie die Sprache funktioniert, und nicht, um uns zu retten.

In anderen Fällen ist es albern, sich Gedanken darüber zu machen, wie eine Bedingung am „schnellsten“ iteriert oder überprüft werden kann.Anstatt Tests zu schreiben, die Millionen von Versuchen erfordern, um einen nachweisbaren (aber unbedeutenden) Unterschied festzustellen, konzentrieren Sie sich auf Klarheit.

Wenn jemand anderes (Sie könnten es sein!) diesen Code in einem Monat oder einem Jahr in die Hand nimmt, ist Klarheit das Wichtigste.

In diesem Fall ist Ihr erstes Beispiel kürzer, klarer und erfordert keine Wiederholung.

Entsprechend Dieser Artikel PHP führt eine Kurzschlussauswertung durch, was bedeutet, dass die zweite nicht einmal ausgewertet wird, wenn die erste Bedingung erfüllt ist.Es ist auch ganz einfach zu testen (aus dem Artikel):

<?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
}

?>

Das Kurzschließen dient nicht der Optimierung.Der Hauptzweck besteht darin, den Aufruf von Code zu vermeiden, der nicht funktioniert, aber dennoch zu einem lesbaren Test führt.Beispiel:

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

Beachten Sie, dass array[i] sehr wohl eine Zugriffsverletzung erleiden kann, wenn i außerhalb des Bereichs liegt und das Programm abstürzt.Somit ist dieses Programm sicherlich auf Kurzschlüsse der Auswertung angewiesen!

Ich glaube, dass dies weitaus häufiger der Grund dafür ist, Ausdrücke auf diese Weise zu schreiben, als Optimierungsbedenken.

Während der Einsatz von Kurzschlüssen zu Optimierungszwecken oft übertrieben ist, gibt es sicherlich auch andere zwingende Gründe, ihn zu nutzen.Ein solches Beispiel (in C++) ist das folgende:

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

Um dies zu gewährleisten, setzt man hier auf Kurzschlüsse pObj wurde vor der Dereferenzierung zugewiesen.Das ist weitaus prägnanter als die Verschachtelung if Aussagen.

Da dies als sprachunabhängig gekennzeichnet ist, melde ich mich dazu.Zumindest für Perl ist die erste Option ausreichend, ich kenne mich mit PHP nicht aus.Die Auswertung erfolgt von links nach rechts und bricht ab, sobald die Bedingung erfüllt ist.

In den meisten Sprachen mit angemessener Optimierung funktioniert Ersteres einwandfrei.

Der | ist ein bitweiser Operator in PHP.Es bedeutet nicht $a OR $b, genau.Sie sollten das Doppelrohr verwenden.Und ja, wie bereits erwähnt, führt PHP eine Kurzschlussauswertung durch.In ähnlicher Weise gilt, wenn die erste Bedingung eines && Wenn die Klausel „falsch“ ergibt, wertet PHP den Rest der Klausel ebenfalls nicht aus.

VB.net hat zwei wunderbare Ausdrücke namens „OrElse“ und „AndAlso“

OrElse schließt sich selbst kurz, wenn es zum ersten Mal eine True-Bewertung erreicht, und führt den gewünschten Code aus.

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

AndAlso schließt sich beim ersten Mal selbst kurz, wenn eine falsche Auswertung erfolgt, und wertet den Code innerhalb des Blocks nicht aus.

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

Ich finde beides hilfreich.

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