switch-case vs. if-else?


  • Mod

    Tomot schrieb:

    50 kaskadierte if-else wie im Beispiel oben sind hingegen eindeutig, das ist lausiger Programmierstil (und wird wahrscheinlich von Programmierern gemacht, die der Meinung sind, switch-case sind nur für akademische Betrachtungen geeignet und werden im realen Code nie gebraucht).

    Das ist ja nicht zum Aushalten! Du kapierst nicht einmal, was andere gesagt haben, aber machst dich darüber lustig. Wenn man in einem Programm an einer Stelle 50 Verzweigungen hat, ist das Problem ist nicht, dass man diese nicht als switch schreiben sollte, sondern das Problem ist dann, dass man in deinem Programm 50 Verzweigungen an einer Stelle hat! Aber das kapiert wohl jemand nicht, der anscheinend wirklich seine Zustandsänderungen hart im Code codiert hat und auch noch stolz darauf ist, wie professionell das doch ist, solch ein komplexes Programm geschrieben zu haben 🙄



  • Tomot schrieb:

    Hi,

    ab wie vielen Bedingungen ist denn ein switch-case einem

    if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    else ...
    

    vorzuziehen?

    So weit ich mich erinnere war switch-case auf Grund irgend welcher CPU-Jumptables irgendwann effektiver!?

    Danke!

    Sobald größer/kleiner Vergleiche hast, musst du if(-else) nehmen.

    Musst du nur schauen ob dein Wert einem bestimmten anderen Wert aus einer überschaubaren Menge entspricht nimmst du switch.

    Vergleichst du aber nur mit einem Wert, dann kannst du auch wieder if(-else) nehmen.

    Beachte hierbei, mit switch kann man elegante Sachen machen.
    Man kann z.b. eine Abfolge von Ausführungen durchrutschen lassen.

    Man beachte, es ist kein break gesetzt, d.h. sobald eine Bedingung erfüllt ist, sind auch alle Folgebedingungen erfüllt, bzw. wird die Anweisung daraus ausgegeben:

    switch(bla) {
    case A: ;
    case B: ;
    case C: ;
    default: ;
    }
    

    ein verständliches Beispiel:
    Frage: Welche Wochentage folgen auf den XY?

    // Pseudocode
    switch(XY){
    case MO: print MONTAG;
    case DI: print Dienstag;
    case MI: print Mittwoch;
    case DO: print Donnerstag;
    case FR: print Freitag;
    case SA: print Samstag;
    default: print Sonntag;
    ]
    

    Wäre also XY ein Freitag, dann wird auch der Samstag und Sonntag ausgegeben.

    Möchtest du das mit if umsetzen, dann wird das nicht so schön.



  • Und ja, wenn switch möglich und praktikabel ist, dann sollte man es auch nehmen, denn das kann der Compiler besser optimieren.



  • Praktiker schrieb:

    Vergleichst du aber nur mit einem Wert, dann kannst du auch wieder if(-else) nehmen.

    Damit meine ich, wenn man einen Wert mit einem ganz bestimmten Wert vergleicht.

    Z.b. ob bla == TRUE ist.



  • sondern das Problem ist dann, dass man in deinem Programm 50 Verzweigungen an einer Stelle hat! Aber das kapiert wohl jemand nicht, der anscheinend wirklich seine Zustandsänderungen hart im Code codiert hat und auch noch stolz darauf ist

    wenn das keine "richtige" Statemachine ist sondern einfach nur viele if-Statements auf einem Haufen könnte ich dir recht geben - aber was ist wenn seine Statemachine wirklich sehr komplex ist - oder mehrere Transitionmatrizen von Hand zusammengefasst sind? Ist ja auch nicht so das wir alle hier immer den gleichen Projekterfahrungshorizont haben

    btw ist es aber für die Performanzfrage auch unrelevant ob es handgeschriebener oder generierter Code ist - und selten(oder nie) switch zu verwenden ist auch irgendwie seltsam/ungewöhnlich



  • SeppJ schrieb:

    Wenn du viele Bedingungen fest im Code stehen hast, machst du wahrscheinlich etwas falsch. Außerhalb von Beispielcodes habe ich jedenfalls noch nie switch benutzt. Insofern ist es wahrscheinlich müßig, sich darüber große Gedanken zu machen, bevor man nicht wirklich mal auf einen praktischen Fall stößt.

    Für welcher Wochentag ist heute und mach dann etwas entsprechendes ist Switch immer gut zu gebrauchen.
    Wichtig ist nur, dass das, was du ausgeben möchtest, nicht fest im Code ist.

    Zu gebrauchen z.b. für einen Terminplaner.



  • Hab noch etwas vergessen:

    Praktiker schrieb:

    Musst du nur schauen ob dein Wert einem bestimmten anderen Wert aus einer überschaubaren Menge entspricht nimmst du switch.

    Ist die Menge, mit der verglichen werden soll, nicht mehr überschaubar, dann ist weder if/else noch switch das Problem, sondern die Datenstruktur.

    Bsp:
    Wenn du wissen willst, ob ein bestimmtes Wort in einem Wörterbuch vorhanden ist, dann packst du ganz sicher nicht das ganze Wörterbuch in eine Switchanweisung.
    Und eine Kaskade von if Anweisungen machst du da auch nicht.


  • Mod

    Praktiker schrieb:

    Für welcher Wochentag ist heute und mach dann etwas entsprechendes ist Switch immer gut zu gebrauchen.
    Wichtig ist nur, dass das, was du ausgeben möchtest, nicht fest im Code ist.

    Zu gebrauchen z.b. für einen Terminplaner.

    Was möchtest du bei einem Terminplaner switchen? Ein Terminplaner ist doch ein Paradebeispiel für eine Anwendung, bei der möglichst viel dynamisch gehalten werden sollte.



  • Was möchtest du bei einem Terminplaner switchen? Ein Terminplaner ist doch ein Paradebeispiel für eine Anwendung, bei der möglichst viel dynamisch gehalten werden sollte.

    es ist doch völlig unrelevant ob die Software sehr dynamisch ist oder nicht - wenn es irgendwo viele If-Statements (z.B. in einer von mehreren fixen Statemachine gibt - die es vielleicht nicht so oft in einem Terminplaner gibt) wo nur ein State verglichen werden sollte man dafür sinnvollerweise switch verwenden



  • und es ist doch eigentlich normal Zustandskomplexität mit If-Statements auf einfache Zustände zu mappen und diesen dann mit switch-case weiter zu verarbeiten - daher verstehe ich diese If-oder-Switch-Frage und die Diskussionen hier nicht wirklich



  • SeppJ schrieb:

    Das ist ja nicht zum Aushalten! Du kapierst nicht einmal, was andere gesagt haben, aber machst dich darüber lustig. Wenn man in einem Programm an einer Stelle 50 Verzweigungen hat, ist das Problem ist nicht, dass man diese nicht als switch schreiben sollte, sondern das Problem ist dann, dass man in deinem Programm 50 Verzweigungen an einer Stelle hat!

    Versuchst du gerade, dich aus dieser Peinlichkeit herauszuwinden? Dann konfrontiere ich dich mal damit, was du TATSÄCHLICH geschrieben hast:

    SeppJ schrieb:

    Wenn du viele Bedingungen fest im Code stehen hast, machst du wahrscheinlich etwas falsch. Außerhalb von Beispielcodes habe ich jedenfalls noch nie switch benutzt.

    Und wieso sollte ich in einer State-Maschine, die 50 Zustände hat, diese 50 Zustände nicht an eine Stelle schreiben? Dann behalte ich wenigstens leicht den Überblick, welcher Zustand zu welchem Funktionsaufruf führt.

    Wenn diese States sich nicht logisch gruppieren lassen, macht es keinen Sinn, sie künstlich zu zerhacken - und kostet im Falle einer sinnlosen Aufpslittung sogar noch zusätzlich Rechenzeit.


  • Mod

    Gast3 schrieb:

    Was möchtest du bei einem Terminplaner switchen? Ein Terminplaner ist doch ein Paradebeispiel für eine Anwendung, bei der möglichst viel dynamisch gehalten werden sollte.

    es ist doch völlig unrelevant ob die Software sehr dynamisch ist oder nicht - wenn es irgendwo viele If-Statements (z.B. in einer von mehreren fixen Statemachine gibt - die es vielleicht nicht so oft in einem Terminplaner gibt) wo nur ein State verglichen werden sollte man dafür sinnvollerweise switch verwenden

    Wenn die Logik dynamisch ist (oder sehr komplex, was bedeutet, dass man ernsthaft in Betracht ziehen sollte, sie dynamisch zu machen), dann würde das ganze halt durch Lookups in passende Datenstrukturen erfolgen, anstatt durch fest-codierte Anweisungen in der Programmlogik. Macht effektiv das gleiche (ein Arrayzugriff und ein Jumptable tun sich nicht viel), hält aber den Code einfacher und flexibler.



  • Gast3 schrieb:

    und es ist doch eigentlich normal Zustandskomplexität mit If-Statements auf einfache Zustände zu mappen und diesen dann mit switch-case weiter zu verarbeiten - daher verstehe ich diese If-oder-Switch-Frage und die Diskussionen hier nicht wirklich

    Dann lies' mal das Ursprungsposting. Es geht um Rechenzeiteinsparung.

    Fakt ist, dass ein Ablauf

    if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    

    um so mehr Zeit benötigt, um so weiter unten die erfüllte Bedingung steht - schlicht weil de CPU jede Bedingung einzeln überprüfen muss.

    Deswegen wurde ja switch-case eingeführt, welches sofort auf den passenden Wert springt. "bedingung" muss hier logischerweise ein Vergleich auf Gleichheit sein, sonst lässt sich switch-case nicht verwenden.

    Das Problem: switch-case hat per se erst mal ein wenig Overhead, weil es mit irgend welchen lustigen Jumptables arbeitet.

    Die eigentliche Frage war hier, ab wie vielen if-else-Kaskadierungen sich ein Ersetzen durch switch-case lohnt, weil dann diese Jumptables effektiver sind, als für einen Durchlauf bis zur letzten Bedingung.

    Nur scheint das eine Frage zu sein, die in diesem Forum noch nicht mal verstanden wird, geschweige denn zu der eine brauchbare Antwort möglich ist.

    Statt dessen glänzt hier ein "Supermoderator" mit geradezu peinlichen Aussagen, vo denen man ernsthaft warnen sollte.



  • @SeppJ

    Wenn die Logik dynamisch ist (oder sehr komplex, was bedeutet, dass man ernsthaft in Betracht ziehen sollte, sie dynamisch zu machen), dann würde das ganze halt durch Lookups in passende Datenstrukturen erfolgen, anstatt durch fest-codierte Anweisungen in der Programmlogik. Macht effektiv das gleiche (ein Arrayzugriff und ein Jumptable tun sich nicht viel), hält aber den Code einfacher und flexibler.

    wieso veränderst du den Kontext der Ursprungsfrage?
    es ging hier nirgends um komplexe dynamische Fallunterscheidungen - die man wo ich dir recht geben lieber anders lösen sollte - aber das war hier einfach nicht die Frage - und wenn du hohe Verarbeitungsraten fährst ist "(ein Arrayzugriff und ein Jumptable tun sich nicht viel)" ziemlich weit aus dem Fenster gelehnt - wir kennen doch gar nicht den Kontext - 1ms Echtzeit, 10 Mio Datenpakete in 10ms, und und und - klar ist es nur wenn man genau dein Beispiel von einem einfachen dynamischen Terminplaner nimmt - mit den Features die nur du kennst und dann damit argumentiert



  • So, damit sich hier nicht noch mehr Unwissenheit, Halbwahrheiten und Gerüchte verbreiten, lasse ich mal an meinen Erkennissen aus anderen Foren teilhaben: die alte switch-case-Geschwindigkeitsregel ist hinfällig.

    Tatsächlich schauen sich (gute) moderne Compiler die verwendeten Werte an und machen aus einem switch-case - wenn sinnvoll - schon mal das Äquivalent einer if-else-Kette. Oder eine Jumptable. Oder einen binären Abfragebaum. Oder was an der Stelle sonst sinvoll ist.

    Die daraus abzuleitende Regel wäre eher, switch-case immer dann zu verwenden, wenn es übersichtlicher wird, also IMHO so ab drei Abfragen.


  • Mod

    Gast3 schrieb:

    wieso veränderst du den Kontext der Ursprungsfrage?

    Was ist denn die Ursprungsfrage? Ob man switch in der Praxis oft (oder überhaupt) braucht? Das war jedenfalls die Frage, die ich dir beantworten wollte. Dass ich bewusst nicht auf Tomots Unsinn eingehe, habe ich bereits klar gemacht.


  • Mod

    Tomot schrieb:

    Tatsächlich schauen sich (gute) moderne Compiler die verwendeten Werte an und machen aus einem switch-case - wenn sinnvoll - schon mal das Äquivalent einer if-else-Kette. Oder eine Jumptable. Oder einen binären Abfragebaum. Oder was an der Stelle sonst sinvoll ist.

    Erste Antwort hier in diesem ach so inkompetenten Forum:

    afdasfd schrieb:

    oO

    Erinnerungen mögen trügen. Im Grunde sollte es egal sein. Der Compiler dürfte das zum gleichen Code verhackstücken.

    Du kannst ja mal zum Test dem Compiler deiner Wahl sagen, dass er den Assembler Code ausspucken soll. Dort kannst du dann schön vergleichen.



  • SeppJ schrieb:

    Erste Antwort hier in diesem ach so inkompetenten Forum:

    Dir muss man echt lesen helfen, oder? Diese Antwort beschreibt, dass ein if-else auch mal in ein switch-case-Äquivalent umgewandelt wird.

    Davon habe ich aber NICHTS geschrieben! Es scheint nur das Gegenteil der Fall zu sein, dass ein switch-case auch mal zu einem if-else-Äquivalent (oder eben zu ganz was anderem) umgewandelt wird.

    Und dass if-else nicht zwangsläufig zum gleichen Code wie switch-case wird, kann man unter gcc.godbolt.org ganz leicht überprüfen.



  • Unregistrierte sind mir sowieso suspekt.
    SeppJ ist ein hochanständiger und wissender Mensch, ihr kleinen Schei**haufen da außen.



  • SeppJ schrieb:

    Praktiker schrieb:

    Für welcher Wochentag ist heute und mach dann etwas entsprechendes ist Switch immer gut zu gebrauchen.
    Wichtig ist nur, dass das, was du ausgeben möchtest, nicht fest im Code ist.

    Zu gebrauchen z.b. für einen Terminplaner.

    Was möchtest du bei einem Terminplaner switchen? Ein Terminplaner ist doch ein Paradebeispiel für eine Anwendung, bei der möglichst viel dynamisch gehalten werden sollte.

    Z.B. welcber Tag ist heute?

    Dinge die du regelmäßig machst, sind sicherlich an einem bestimmten Wochentag, also wird da nach dem Wochentag geswitched.
    Und was an dem Wochentag stattfindet, das entnimmst du dann der Datenstruktur.


Anmelden zum Antworten