2010-12-02 17 views
11

Abgesehen von Code Lesbarkeit, warum ist es schlecht, viele If-Anweisungen zu verwenden?Nachteile der Verwendung von vielen if-Anweisungen

+0

Die meisten Programme haben viele If-Anweisungen. Ich habe nie gehört, dass das schlecht ist. Beziehen Sie sich vielleicht auf * tief verschachtelte * if-Statements? –

+1

Ich weiß es nicht, oder? In welchem ​​Kontext? –

+0

Ein Problem ist, dass Sie viele Codepfade einführen. Dies macht es schwierig, den Code zu testen. Es kann schwierig sein, jeden Pfad einzeln auszulösen. Es ist besser, brauchbare Designmuster wie die erwähnte Strategie zu finden. Das würde es Ihnen ermöglichen, jeden einzelnen Codepfad viel einfacher zu testen. –

Antwort

11

Wenn Sie viele If-Anweisungen nacheinander haben, dann ist eine Switch-Case-Anweisung sinnvoller. Zumindest hat es eine feste Antwortzeit für jede mögliche Unterbrechung, da es nicht durch alle if-Anweisungen fallen muss.

Viele if (und anderes) Erklärung gibt in der Regel

a) Violation of Single responsibility Principle

b) Sie benötigen wegen der Prozessorarchitektur Refactoring hinaus in Strategy Design Pattern

+5

Eine 'switch' Anweisung muss nicht unbedingt eine feste Antwortzeit haben (zumindest nicht in C#). Allerdings ist die Sorge um diese Art von Ultramikro-Optimierungen für ziemlich alle Zeitverschwendung. – LukeH

+2

@LukeH: Ich habe tatsächlich den größten Teil des gestrigen Tages damit verbracht, Zweigstrafen in meiner App aufzuspüren und sie entweder zu eliminieren oder durch verzweigungslose Algorithmen zu ersetzen, um eine 250ms-Hitch auf 50ms zu reduzieren. – Crashworks

+0

@Crashworks: Deshalb habe ich * "fast jeder" * gesagt und nicht nur eine Decke * "alle" *. Ich vermute, dass du eine der Ausnahmen bist, die die Regel beweisen. – LukeH

0
if(A) 
{ 
}else 
if(B) 
{ 
}else 
if(C) 
{ 
}else 
if(D) 
{ 
}else 
{ } 

Alle if s müssen noch "berechnet" get es so etwas wie "O (n)" zu machen. Es sollte vermieden werden, wenn möglich und verwenden switch(Lalala)

+1

Wenn Sie "else" verwenden, werden die verbleibenden 'if's nach einer übereinstimmenden Bedingung nicht ausgewertet. Es ist der schlimmste Fall nur, wenn kein 'if' passt und der letzte' else' ausgeführt wird. – TheVillageIdiot

+0

@TheVillage, ja das ist was ich meine. Der Standardwert: case in switch. z.B. Wenn C die übereinstimmende Bedingung wäre, müssten A und B noch ausgewertet werden. aber mit Schalter konnten wir direkt nach C "springen". – Muggen

+0

@Henk, tut mir leid, ich bin nur ein Student. – Muggen

1

Manchmal ist es effizienter, eine zu finden Möglichkeit, Verzweigungen überhaupt zu vermeiden; Dies könnte als ein Nachteil von if Aussagen betrachtet werden.

0

Eine andere Möglichkeit - es hängt davon ab, was die if-Anweisungen tun. In einigen Fällen können sie Entscheidungen treffen, die besser durch eine ordnungsgemäß entworfene Klassenhierarchie erledigt werden.

Können Sie einige Beispiele von if-Anweisungen posten, die Ihnen gesagt wurden, dass sie schlecht sind?

13

Jedes If/Else, das Sie schreiben, erhöht die Anzahl der Codepfade, die Sie testen müssen.

0

If-Anweisung kann einen Stillstand in der Pipeline erzeugen. Sie können über Pipeline Gefahren here lesen. Für sehr performancekritische Anwendungen ist es daher keine gute Idee, viele if-Anweisungen in einer großen Schleife zu haben. Überprüfen Sie auch this Artikel über Verzweigungsprognose in modernen Prozessoren und Benchmarks verschiedener if-Bedingungen.

Auch sehe ich eine Menge Leute über Fallaussage sprechen. Überprüfen Sie this SO Thread.

Und für das Ende, wiki article über Pipeline, die wahrscheinlich jeder Programmierer hätte lesen sollen.

Ich hoffe, es hilft.

1

Chusdad hat Recht. Switch-Struktur ist besser als mehrere Wenn-sonst. Der nächste Ansatz besteht darin, enum als einen Umschaltschlüssel zu verwenden. In diesem Fall erhalten Sie eine Warnung, wenn Sie vergessen haben, eines der Enum-Elemente in Ihrem Switch anzugeben.

Aber wenn Sie Enum und Schalter verwenden, gehen Sie für besseres Design voran: Entfernen Sie Schalter überhaupt!

Erklären Sie abstrakte Geschäftsmethode in Ihrer enum. Implementieren Sie es für jedes Aufzählungselement. Der Aufruf von enumElement.theMethod() anstelle von switch.

Hier ist ein Beispiel.

enum Foo { 
    ONE { 
     public void foo() { 
      // do something 
     } 
    }, 

    TWO { 
     public void foo() { 
      // do something 
     } 
    }, 

    ; 
    public abstract void foo(); 
} 

Hier ist der Code, der diese verwendet:

Foo.valueOf(System.getProperty("foo")).foo(); 

diese Zeile vergleichen mit den folgenden:

String foo = System.getProperty("foo"); 
    if("ONE".equals(foo)) { 
     //..... 
    } else if("ONE".equals(foo)) { 
     //..... 
    } else { 
     //..... 
    } 

Ich denke, dass keine Kommentare erforderlich sind.

3

Nun, die Frage, die ich zurückfragen muss, ist "im Gegensatz zu was"?

Wenn Sie im Gegensatz zu einer switch-Anweisung, dann so gut wie Lesbarkeit kann es manchmal effizienter sein. In der Regel (sicherlich in C#, wahrscheinlich in den anderen) unterhalb einer bestimmten Anzahl von Zweigen wird es nur in eine Reihe von if-Anweisungen umgewandelt, aber darüber hinaus wird es in eine Hash-basierte Nachschlage- und Sprungfunktion umgewandelt wahrscheinlich im Durchschnitt schneller.

Alternativ können Sie, wenn Sie die relative Häufigkeit verschiedener Fälle gut kennen, mit if-Anweisungen effizienter arbeiten. Z.B. Wenn 95% der Fälle mit dem ersten Zweig übereinstimmen, 4% mit dem zweiten und 1% mit dem Rest übereinstimmen, kann dies für die 95% der Fälle eine bessere Leistung erbringen, indem ein einzelner Vergleich durchgeführt wird und in diesem Fall möglicherweise nicht verzweigt wird.

So. Vielleicht gibt es einen Effizienzgewinn in diesem Fall.

Dennoch zählt Lesbarkeit für eine Menge. Als extremes Beispiel gibt es eine Turing-vollständige Sprache, die nur dafür entworfen wurde, zu sehen, wie klein ein Compiler für eine Turing-vollständige Sprache sein könnte. Der Designer hat die Sprache "brainf ** k" genannt. Dies ist ein großer Kommentar zur Bedeutung von lesbarem Code in der realen Programmierung.

Jetzt ist ein größeres Problem mit einer großen Anzahl von if-Anweisungen, dass es oft anzeigt, dass Sie etwas über diese if-Anweisungen modellieren, die mit einer Klassenhierarchie besser modelliert werden könnten. In gewisser Weise ist dies nur ein weiterer Aspekt der Lesbarkeit (vorausgesetzt, das Programm funktioniert in beiden Richtungen). Es geht jedoch um die Lesbarkeit - und Verständlichkeit - des Programms als Ganzes. Es wird massive Auswirkungen auf das mentale Modell, das Sie haben, des Programms, Erweiterbarkeit und beeinflussen nicht nur, wie gut Sie es halten können, aber Sie werden sich so gut wie möglich vorstellen. Es kann leicht der Unterschied zwischen einem Programm sein, das zu einer Zeitverknappung wird, bis jemand herauskommt, wie man es loswerden kann, und einem, das wächst, um weiterhin eine Kapitalrendite zu erzielen.

0

Wenn Sie feststellen, dass Sie immer wieder if Anweisungen für die gleiche Bedingung schreiben, ist es leichter, diesen Teil der Typhierarchie zu erstellen.

Der Grund ist, dass, wenn sich die Logik für diese Bedingung ändert, Sie alle if Anweisung suchen müssen, die es verwendet und es ändern.

Wenn diese Logik in einer Klassenhierarchie gekapselt ist, sollten Sie sie nur einmal ändern.

Verwandte Themen